diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2013-06-08 13:29:58 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2013-06-08 13:29:58 +0000 |
commit | 89578fd4398130e24bf44e805f8f9688f72be7e1 (patch) | |
tree | 7869f1c400cd3d1f1d8a2c6a442cf5b602ea1c2b /clang/lib/Sema/SemaDecl.cpp | |
parent | ea7bb570580d1a82c8654d0ee3ce6b0a4419a35b (diff) | |
download | bcm5719-llvm-89578fd4398130e24bf44e805f8f9688f72be7e1.tar.gz bcm5719-llvm-89578fd4398130e24bf44e805f8f9688f72be7e1.zip |
Recognition of empty structures and unions is moved to semantic stage
Differential Revision: http://llvm-reviews.chandlerc.com/D586
llvm-svn: 183609
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7be376e60f0..e6a89461b45 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11235,6 +11235,41 @@ void Sema::ActOnFields(Scope* S, if (Record->hasAttrs()) CheckAlignasUnderalignment(Record); + + // Check if the structure/union declaration is a language extension. + if (!getLangOpts().CPlusPlus) { + bool ZeroSize = true; + bool UnnamedOnly = true; + unsigned UnnamedCnt = 0; + for (RecordDecl::field_iterator I = Record->field_begin(), + E = Record->field_end(); UnnamedOnly && I != E; ++I) { + if (I->isUnnamedBitfield()) { + UnnamedCnt++; + if (I->getBitWidthValue(Context) > 0) + ZeroSize = false; + } else { + UnnamedOnly = ZeroSize = false; + } + } + + // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in + // C++. + if (ZeroSize) { + if (UnnamedCnt == 0) + Diag(RecLoc, diag::warn_empty_struct_union_compat) << Record->isUnion(); + else + Diag(RecLoc, diag::warn_zero_size_struct_union_compat) << Record->isUnion(); + } + + // Structs without named members are extension in C (C99 6.7.2.1p7), but + // are accepted by GCC. + if (UnnamedOnly) { + if (UnnamedCnt == 0) + Diag(RecLoc, diag::ext_empty_struct_union) << Record->isUnion(); + else + Diag(RecLoc, diag::ext_no_named_members_in_struct_union) << Record->isUnion(); + } + } } else { ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); |