Fix bug in __extension__ handling for declarations, from Abramo
Bagnara with a fix from Enea Zaffanella!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80094 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 8a09fa5..226cbe8 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -256,6 +256,7 @@
/// entirely silenced, no matter how they are mapped.
void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
+ bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
/// setDiagnosticMapping - This allows the client to specify that certain
/// warnings are ignored. Notes can never be mapped, errors can only be
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 06d05f7..9d8a6f0 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -853,6 +853,9 @@
DeclaratorChunk::ParamInfo InlineParams[16];
bool InlineParamsUsed;
+ /// Extension - true if the declaration is preceded by __extension__.
+ bool Extension : 1;
+
friend struct DeclaratorChunk;
public:
@@ -861,7 +864,7 @@
Kind(DK_Abstract),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), AttrList(0), AsmLabel(0), Type(0),
- InlineParamsUsed(false) {
+ InlineParamsUsed(false), Extension(false) {
}
~Declarator() {
@@ -1090,6 +1093,9 @@
void setAsmLabel(ActionBase::ExprTy *E) { AsmLabel = E; }
ActionBase::ExprTy *getAsmLabel() const { return AsmLabel; }
+ void setExtension(bool Val = true) { Extension = Val; }
+ bool getExtension() const { return Extension; }
+
ActionBase::TypeTy *getDeclaratorIdType() const { return Type; }
OverloadedOperatorKind getOverloadedOperator() const { return OperatorKind; }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 8cb8ffd..c29f601 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1509,10 +1509,19 @@
// Convert them all to fields.
for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
FieldDeclarator &FD = FieldDeclarators[i];
+ DeclPtrTy Field;
// Install the declarator into the current TagDecl.
- DeclPtrTy Field = Actions.ActOnField(CurScope, TagDecl,
- DS.getSourceRange().getBegin(),
- FD.D, FD.BitfieldSize);
+ if (FD.D.getExtension()) {
+ // Silences extension warnings
+ ExtensionRAIIObject O(Diags);
+ Field = Actions.ActOnField(CurScope, TagDecl,
+ DS.getSourceRange().getBegin(),
+ FD.D, FD.BitfieldSize);
+ } else {
+ Field = Actions.ActOnField(CurScope, TagDecl,
+ DS.getSourceRange().getBegin(),
+ FD.D, FD.BitfieldSize);
+ }
FieldDecls.push_back(Field);
}
} else { // Handle @defs
@@ -2016,6 +2025,8 @@
void Parser::ParseDeclaratorInternal(Declarator &D,
DirectDeclParseFunction DirectDeclParser) {
+ if (Diags.hasAllExtensionsSilenced())
+ D.setExtension();
// C++ member pointers start with a '::' or a nested-name.
// Member pointers get special handling, since there's no place for the
// scope spec in the generic path below.
diff --git a/test/Sema/implicit-int.c b/test/Sema/implicit-int.c
index 9eab953..1a81cc5 100644
--- a/test/Sema/implicit-int.c
+++ b/test/Sema/implicit-int.c
@@ -24,7 +24,7 @@
}
struct foo {
- __extension__ __attribute__((packed)) x : 4; // expected-warning {{type specifier missing, defaults to 'int'}}
+ __extension__ __attribute__((packed)) x : 4;
};