Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1156,7 +1156,7 @@ def FallThrough : StmtAttr { let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">, - CXX11<"clang", "fallthrough">]; + CXX11<"clang", "fallthrough">, GCC<"fallthrough">]; // let Subjects = [NullStmt]; let Documentation = [FallthroughDocs]; } Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -99,6 +99,7 @@ ParenBraceBracketBalancer BalancerRAIIObj(*this); ParsedAttributesWithRange Attrs(AttrFactory); + MaybeParseGNUAttributes(Attrs); MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true); if (!MaybeParseOpenCLUnrollHintAttribute(Attrs)) return StmtError(); Index: lib/Sema/AnalysisBasedWarnings.cpp =================================================================== --- lib/Sema/AnalysisBasedWarnings.cpp +++ lib/Sema/AnalysisBasedWarnings.cpp @@ -1215,7 +1215,7 @@ tok::r_square, tok::r_square }; - bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17; + bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17 && !PP.getLangOpts().C2x; StringRef MacroName; if (PreferClangAttr) @@ -1224,24 +1224,19 @@ MacroName = PP.getLastMacroWithSpelling(Loc, FallthroughTokens); if (MacroName.empty() && !PreferClangAttr) MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens); - if (MacroName.empty()) - MacroName = PreferClangAttr ? "[[clang::fallthrough]]" : "[[fallthrough]]"; + if (MacroName.empty()) { + if (!PreferClangAttr) + MacroName = "[[fallthrough]]"; + else if (PP.getLangOpts().CPlusPlus) + MacroName = "[[clang::fallthrough]]"; + else + MacroName = "__attribute__ ((fallthrough))"; + } return MacroName; } static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, bool PerFunction) { - // Only perform this analysis when using [[]] attributes. There is no good - // workflow for this warning when not using C++11. There is no good way to - // silence the warning (no attribute is available) unless we are using - // [[]] attributes. One could use pragmas to silence the warning, but as a - // general solution that is gross and not in the spirit of this warning. - // - // NOTE: This an intermediate solution. There are on-going discussions on - // how to properly support this warning outside of C++11 with an annotation. - if (!AC.getASTContext().getLangOpts().DoubleSquareBracketAttributes) - return; - FallthroughMapper FM(S); FM.TraverseStmt(AC.getBody()); @@ -1281,7 +1276,8 @@ SourceLocation L = Label->getBeginLoc(); if (L.isMacroID()) continue; - if (S.getLangOpts().CPlusPlus11) { + if (S.getLangOpts().CPlusPlus11 || S.getLangOpts().C99 || + S.getLangOpts().GNUMode) { const Stmt *Term = B->getTerminatorStmt(); // Skip empty cases. while (B->empty() && !Term && B->succ_size() == 1) { Index: test/Sema/address_spaces.c =================================================================== --- test/Sema/address_spaces.c +++ test/Sema/address_spaces.c @@ -9,7 +9,7 @@ void foo(_AS3 float *a, _AS1 float b) // expected-error {{parameter may not be qualified with an address space}} { - _AS2 *x;// expected-warning {{type specifier missing, defaults to 'int'}} + _AS2 *x;// expected-error {{use of undeclared identifier 'x'}} _AS1 float * _AS2 *B; int _AS1 _AS2 *Y; // expected-error {{multiple address spaces specified for type}} Index: test/Sema/block-literal.c =================================================================== --- test/Sema/block-literal.c +++ test/Sema/block-literal.c @@ -41,8 +41,8 @@ foo: takeblock(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}} - __block y = 7; // expected-warning {{type specifier missing, defaults to 'int'}} - takeblock(^{ y = 8; }); + __block y = 7; // expected-error {{use of undeclared identifier 'y'}} + takeblock(^{ x = 8; }); // expected-error {{use of undeclared identifier 'y'}} } Index: test/Sema/fallthrough-attr.c =================================================================== --- test/Sema/fallthrough-attr.c +++ test/Sema/fallthrough-attr.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -std=gnu89 -verify -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -std=gnu99 -verify -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -std=c2x -DC2X -verify -Wimplicit-fallthrough %s + +int fallthrough_attribute_spelling(int n) { + switch (n) { + case 0: + n++; + case 1: + #if defined(C2X) + // expected-warning@-2{{unannotated fall-through between switch labels}} expected-note@-2{{insert '[[fallthrough]];' to silence this warning}} expected-note@-2{{insert 'break;' to avoid fall-through}} + #else + // expected-warning@-4{{unannotated fall-through between switch labels}} expected-note@-4{{insert '__attribute__ ((fallthrough));' to silence this warning}} expected-note@-4{{insert 'break;' to avoid fall-through}} + #endif + n++; + __attribute__ ((fallthrough)); + case 2: + n++; + break; + } + return n; +} Index: test/SemaCXX/switch-implicit-fallthrough.cpp =================================================================== --- test/SemaCXX/switch-implicit-fallthrough.cpp +++ test/SemaCXX/switch-implicit-fallthrough.cpp @@ -329,3 +329,15 @@ } return n; } + +int fallthrough_attribute_spelling(int n) { + switch (n) { + case 0: + n++; + __attribute__ ((fallthrough)); + case 1: + n++; + break; + } + return n; +} Index: test/SemaCXX/warn-unused-label-error.cpp =================================================================== --- test/SemaCXX/warn-unused-label-error.cpp +++ test/SemaCXX/warn-unused-label-error.cpp @@ -18,9 +18,9 @@ } void h() { - D: // expected-warning {{unused label 'D'}} + D: #pragma weak unused_local_static - __attribute__((unused)) // expected-warning {{declaration does not declare anything}} + __attribute__((unused)) // expected-error {{'unused' attribute cannot be applied to a statement}} ; } }