Author: sepavloff Date: Sun Aug 4 03:08:51 2019 New Revision: 367779 URL: http://llvm.org/viewvc/llvm-project?rev=367779&view=rev Log: [Parser] Emit descriptive diagnostic for misplaced pragma
If a class or struct or union declaration contains a pragma that is not valid in this context, compiler issues generic error like "expected member name or ';' after declaration specifiers". With this change the error tells that this pragma cannot appear in this declaration. Differential Revision: https://reviews.llvm.org/D64932 Added: cfe/trunk/test/Parser/pragma-fp-contract.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/test/Parser/pragma-attribute-context.cpp cfe/trunk/test/Parser/pragma-fp-contract.c Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=367779&r1=367778&r2=367779&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Aug 4 03:08:51 2019 @@ -974,6 +974,8 @@ def warn_pragma_missing_argument : Warni def warn_pragma_invalid_argument : Warning< "unexpected argument '%0' to '#pragma %1'%select{|; expected %3}2">, InGroup<IgnoredPragmas>; +def err_pragma_misplaced_in_decl : Error<"this pragma cannot appear in %0 declaration">; + // '#pragma clang section' related errors def err_pragma_expected_clang_section_name : Error< "expected one of [bss|data|rodata|text] section kind in '#pragma %0'">; Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=367779&r1=367778&r2=367779&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Aug 4 03:08:51 2019 @@ -4148,6 +4148,14 @@ void Parser::ParseStructUnionBody(Source continue; } + if (tok::isPragmaAnnotation(Tok.getKind())) { + Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl) + << DeclSpec::getSpecifierName( + TagType, Actions.getASTContext().getPrintingPolicy()); + ConsumeAnnotationToken(); + continue; + } + if (!Tok.is(tok::at)) { auto CFieldCallback = [&](ParsingFieldDeclarator &FD) { // Install the declarator into the current TagDecl. Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=367779&r1=367778&r2=367779&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sun Aug 4 03:08:51 2019 @@ -3134,6 +3134,13 @@ Parser::DeclGroupPtrTy Parser::ParseCXXC TagDecl); default: + if (tok::isPragmaAnnotation(Tok.getKind())) { + Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl) + << DeclSpec::getSpecifierName(TagType, + Actions.getASTContext().getPrintingPolicy()); + ConsumeAnnotationToken(); + return nullptr; + } return ParseCXXClassMemberDeclaration(AS, AccessAttrs); } } Modified: cfe/trunk/test/Parser/pragma-attribute-context.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-attribute-context.cpp?rev=367779&r1=367778&r2=367779&view=diff ============================================================================== --- cfe/trunk/test/Parser/pragma-attribute-context.cpp (original) +++ cfe/trunk/test/Parser/pragma-attribute-context.cpp Sun Aug 4 03:08:51 2019 @@ -31,8 +31,7 @@ int c = my_ns::nested::h(); // expected- struct InStruct { // FIXME: This asserts in Objective-C++! - // FIXME: This is a horrible diagnostic! #ifndef __OBJC__ - BEGIN_PRAGMA // expected-error {{expected member name or ';' after declaration specifiers}} + BEGIN_PRAGMA // expected-error {{this pragma cannot appear in struct declaration}} #endif }; Modified: cfe/trunk/test/Parser/pragma-fp-contract.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-fp-contract.c?rev=367779&r1=367778&r2=367779&view=diff ============================================================================== --- cfe/trunk/test/Parser/pragma-fp-contract.c (original) +++ cfe/trunk/test/Parser/pragma-fp-contract.c Sun Aug 4 03:08:51 2019 @@ -10,3 +10,16 @@ void f2(void) { #pragma STDC FP_CONTRACT OFF #pragma STDC FP_CONTRACT ON } + +struct S1 { +// expected-error@+1 {{this pragma cannot appear in struct declaration}} +#pragma STDC FP_CONTRACT ON + float f1; +}; + +union U1 { + float f1; + float f2; +// expected-error@+1 {{this pragma cannot appear in union declaration}} +#pragma STDC FP_CONTRACT ON +}; Added: cfe/trunk/test/Parser/pragma-fp-contract.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-fp-contract.cpp?rev=367779&view=auto ============================================================================== --- cfe/trunk/test/Parser/pragma-fp-contract.cpp (added) +++ cfe/trunk/test/Parser/pragma-fp-contract.cpp Sun Aug 4 03:08:51 2019 @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f1(void) { + int x = 0; +/* expected-error@+1 {{'#pragma fp_contract' can only appear at file scope or at the start of a compound statement}} */ +#pragma STDC FP_CONTRACT ON +} + +void f2(void) { + #pragma STDC FP_CONTRACT OFF + #pragma STDC FP_CONTRACT ON +} + +struct S1 { +// expected-error@+1 {{this pragma cannot appear in struct declaration}} +#pragma STDC FP_CONTRACT ON + float f1; +}; + +union U1 { + float f1; + float f2; +// expected-error@+1 {{this pragma cannot appear in union declaration}} +#pragma STDC FP_CONTRACT ON +}; + +class C1 { + float f1; +// expected-error@+1 {{this pragma cannot appear in class declaration}} +#pragma STDC FP_CONTRACT ON + float f2; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits