diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2014-06-25 17:09:41 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2014-06-25 17:09:41 +0000 |
commit | a826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d (patch) | |
tree | 4d955aea3d73adfaaa7fe5b3097fc1b8f603293f /clang/lib/Sema/SemaDecl.cpp | |
parent | 9029bda8a31c6d2f908fd1d6e6e4d8615c8c76c7 (diff) | |
download | bcm5719-llvm-a826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d.tar.gz bcm5719-llvm-a826147eef05d1d4fa0f3efdd1eeb4c71ae13b9d.zip |
Fix treatment of types defined in function prototype
Types defined in function prototype are diagnosed earlier in C++ compilation.
They are put into declaration context where the prototype is introduced. Later on,
when FunctionDecl object is created, these types are moved into the function context.
This patch fixes PR19018 and PR18963.
Differential Revision: http://reviews.llvm.org/D4145
llvm-svn: 211718
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 90499d2749e..073da57b364 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10874,11 +10874,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC)) SearchDC = SearchDC->getParent(); } - } else if (S->isFunctionPrototypeScope()) { - // If this is an enum declaration in function prototype scope, set its - // initial context to the translation unit. - // FIXME: [citation needed] - SearchDC = Context.getTranslationUnitDecl(); } if (Previous.isSingleResult() && @@ -11351,27 +11346,37 @@ CreateNewDecl: else if (!SearchDC->isFunctionOrMethod()) New->setModulePrivate(); } - + // If this is a specialization of a member class (of a class template), // check the specialization. if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous)) Invalid = true; - - if (Invalid) - New->setInvalidDecl(); - - if (Attr) - ProcessDeclAttributeList(S, New, Attr); // If we're declaring or defining a tag in function prototype scope in C, // note that this type can only be used within the function and add it to // the list of decls to inject into the function definition scope. - if (!getLangOpts().CPlusPlus && (Name || Kind == TTK_Enum) && + if ((Name || Kind == TTK_Enum) && getNonFieldDeclScope(S)->isFunctionPrototypeScope()) { - Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); + if (getLangOpts().CPlusPlus) { + // C++ [dcl.fct]p6: + // Types shall not be defined in return or parameter types. + if (TUK == TUK_Definition && !IsTypeSpecifier) { + Diag(Loc, diag::err_type_defined_in_param_type) + << Name; + Invalid = true; + } + } else { + Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); + } DeclsInPrototypeScope.push_back(New); } + if (Invalid) + New->setInvalidDecl(); + + if (Attr) + ProcessDeclAttributeList(S, New, Attr); + // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. New->setLexicalDeclContext(CurContext); |