From a930e7131c42253c78e3c163cc60b81e8022ebad Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 21 Oct 2012 01:10:01 +0000 Subject: [PATCH] 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 --- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 ++++ clang/lib/Parse/ParseStmt.cpp | 11 ++++++++--- clang/test/CodeGen/fp-contract-pragma.cpp | 1 - clang/test/Parser/pragma-fp-contract.c | 6 ++++++ 4 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 clang/test/Parser/pragma-fp-contract.c diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index b670d6e8cb7a..e01cdb77e55c 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -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< diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index d008b037b0e0..964240df089b 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -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__)) { diff --git a/clang/test/CodeGen/fp-contract-pragma.cpp b/clang/test/CodeGen/fp-contract-pragma.cpp index edb04d82ef54..afd8c43121e6 100644 --- a/clang/test/CodeGen/fp-contract-pragma.cpp +++ b/clang/test/CodeGen/fp-contract-pragma.cpp @@ -39,7 +39,6 @@ template 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 } }; diff --git a/clang/test/Parser/pragma-fp-contract.c b/clang/test/Parser/pragma-fp-contract.c new file mode 100644 index 000000000000..619053f46556 --- /dev/null +++ b/clang/test/Parser/pragma-fp-contract.c @@ -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 +}