r239569 - [modules] Fix assert/crash when parsing and merging a definition of a class with a base-specifier inside a namespace.
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jun 11 15:48:25 PDT 2015
Author: rsmith
Date: Thu Jun 11 17:48:25 2015
New Revision: 239569
URL: http://llvm.org/viewvc/llvm-project?rev=239569&view=rev
Log:
[modules] Fix assert/crash when parsing and merging a definition of a class with a base-specifier inside a namespace.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=239569&r1=239568&r2=239569&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 11 17:48:25 2015
@@ -1850,10 +1850,10 @@ public:
/// struct, or union).
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
+ typedef void *SkippedDefinitionContext;
+
/// \brief Invoked when we enter a tag definition that we're skipping.
- void ActOnTagStartSkippedDefinition(Scope *S, Decl *TD) {
- PushDeclContext(S, cast<DeclContext>(TD));
- }
+ SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
@@ -1870,9 +1870,7 @@ public:
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
SourceLocation RBraceLoc);
- void ActOnTagFinishSkippedDefinition() {
- PopDeclContext();
- }
+ void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context);
void ActOnObjCContainerFinishDefinition();
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=239569&r1=239568&r2=239569&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jun 11 17:48:25 2015
@@ -2724,12 +2724,13 @@ void Parser::SkipCXXMemberSpecification(
ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true,
TagType == DeclSpec::TST_interface);
- Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);
+ auto OldContext =
+ Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);
// Parse the bases but don't attach them to the class.
ParseBaseClause(nullptr);
- Actions.ActOnTagFinishSkippedDefinition();
+ Actions.ActOnTagFinishSkippedDefinition(OldContext);
if (!Tok.is(tok::l_brace)) {
Diag(PP.getLocForEndOfToken(PrevTokLocation),
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=239569&r1=239568&r2=239569&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jun 11 17:48:25 2015
@@ -1081,6 +1081,22 @@ void Sema::PopDeclContext() {
assert(CurContext && "Popped translation unit!");
}
+Sema::SkippedDefinitionContext Sema::ActOnTagStartSkippedDefinition(Scope *S,
+ Decl *D) {
+ // Unlike PushDeclContext, the context to which we return is not necessarily
+ // the containing DC of TD, because the new context will be some pre-existing
+ // TagDecl definition instead of a fresh one.
+ auto Result = static_cast<SkippedDefinitionContext>(CurContext);
+ CurContext = cast<TagDecl>(D)->getDefinition();
+ assert(CurContext && "skipping definition of undefined tag");
+ S->setEntity(CurContext);
+ return Result;
+}
+
+void Sema::ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context) {
+ CurContext = static_cast<decltype(CurContext)>(Context);
+}
+
/// EnterDeclaratorContext - Used when we must lookup names in the context
/// of a declarator's nested name specifier.
///
Modified: cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h?rev=239569&r1=239568&r2=239569&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h (original)
+++ cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h Thu Jun 11 17:48:25 2015
@@ -49,8 +49,8 @@ template<typename T = int, int N = 3, te
namespace NS {
struct A {};
- template<typename T> struct B {};
- template<typename T> struct B<T*> {};
- template<> struct B<int> {};
+ template<typename T> struct B : A {};
+ template<typename T> struct B<T*> : B<char> {};
+ template<> struct B<int> : B<int*> {};
inline void f() {}
}
More information about the cfe-commits
mailing list