When used in a compound expression FP_CONTRACT should proceed all explicit

declarations and statements. Emit an error if the FP_CONTRACT is used
later in a compound statement.

llvm-svn: 166383
This commit is contained in:
Lang Hames 2012-10-21 01:10:01 +00:00
parent cdd40bdc05
commit a930e7131c
4 changed files with 18 additions and 4 deletions

View File

@ -729,6 +729,10 @@ def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">;
def warn_pragma_unused_expected_punc : Warning<
"expected ')' or ',' in '#pragma unused'">;
// - #pragam fp_contract
def err_pragma_fp_contract_scope : Error<
"'#pragma fp_contract' should only appear at file scope or at the start of a "
"compound expression">;
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<

View File

@ -280,9 +280,10 @@ Retry:
return StmtEmpty();
case tok::annot_pragma_fp_contract:
ProhibitAttributes(Attrs);
HandlePragmaFPContract();
return StmtEmpty();
Diag(Tok, diag::err_pragma_fp_contract_scope);
ConsumeToken();
return StmtError();
case tok::annot_pragma_opencl_extension:
ProhibitAttributes(Attrs);
@ -728,6 +729,10 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
StmtVector Stmts;
// Parse FP_CONTRACT if present.
if (Tok.is(tok::annot_pragma_fp_contract))
HandlePragmaFPContract();
// "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are
// only allowed at the start of a compound stmt regardless of the language.
while (Tok.is(tok::kw___label__)) {

View File

@ -39,7 +39,6 @@ template<typename T> class fp_contract_4 {
float method(float a, float b, float c) {
#pragma STDC FP_CONTRACT ON
return a * b + c;
#pragma STDC FP_CONTRACT OFF
}
};

View File

@ -0,0 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
void f1(void) {
int x = 0;
/* expected-error {{'#pragma fp_contract' should only appear at file scope or at the start of a compound expression}} */ #pragma STDC FP_CONTRACT ON
}