SIGSEGV in call to Sema::PerformPendingInstantiations() in Clang 3.2

This email describes a SIGSEGV I'm experiencing with Clang 3.2 when calling Sema::PerformPendingInstantiations(). A patch against latest SVN is attached which resolves the SIGSEGV. However, it appears that the call to Sema::PerformPendingInstantiations() is resulting in a call to Sema::getCurScope() which, according to its comments, should never be called during template instantiation. The purpose of this email is to:

1) Request that the attached patch be applied to SVN. The patch is trivial - it just adds missing initialization of the Sema::CurScope pointer within the Sema constructor.

2) Clarify whether the eventual call into Sema::getCurScope() from within Sema::PerformPendingInstantiations() represents an additional bug which should be addressed.

I experienced the SIGSEGV in code that calls ASTUnit::LoadFromASTFile() to load an AST file produced with the 'clang -emit-ast' driver option. ASTUnit::LoadFromASTFile() creates an instance of the Sema class, but a corresponding Parser instance is not created. AST files may contain pending template instantiations. I have a call to Sema::PerformPendingInstantiations() to complete them. The SIGSEGV occurs when the Sema::CurScope pointer is dereferenced. I debugged the problem and discovered that the Sema constructor (there is only one) is failing to initialize the CurScope member. The comments for CurScope indicate that the Parser maintains this pointer. In my case, there is no Parser instance, hence no initialization occurs resulting in a spurious SIGSEGV. Initializing CurScope to NULL in the Sema constructor avoids the SIGSEGV. CurScope is referenced by Sema::getCurScope() which has the following comment:

include/clang/Sema/Sema.h:
7547 /// \brief Retrieve the parser's current scope.
7548 ///
7549 /// This routine must only be used when it is certain that semantic analysis
7550 /// and the parser are in precisely the same context, which is not the case
7551 /// when, e.g., we are performing any kind of template instantiation.
7552 /// Therefore, the only safe places to use this scope are in the parser
7553 /// itself and in routines directly invoked from the parser and *never* from
7554 /// template substitution or instantiation.
7555 Scope *getCurScope() const { return CurScope; }

The following stack trace demonstrates that calls to Sema::PerformPendingInstantiations() eventually call into Sema::getCurScope(). The stack trace corresponds to the occurrence of the SIGSEGV. The call to Sema::getCurScope() occurs in Sema::getScopeForContext(). Note that the 'this' pointer provided for the call to Scope::getFlags() is invalid.

#0 0x000000000118ffaa in clang::Scope::getFlags (this=0x2f) at .../llvm-3.2/tools/clang/include/clang/Sema/Scope.h:170
#1 0x000000000120c411 in clang::Sema::getScopeForContext (this=0x2af0cb0, Ctx=0x2b2b1c0) at .../llvm-3.2/tools/clang/lib/Sema/Sema.cpp:955
#2 0x0000000001310891 in clang::Sema::DeclareImplicitCopyConstructor (this=0x2af0cb0, ClassDecl=0x2b2b188) at .../llvm-3.2/tools/clang/lib/Sema/SemaDeclCXX.cpp:8836
#3 0x0000000001456552 in clang::Sema::LookupConstructors (this=0x2af0cb0, Class=0x2b2b188) at .../llvm-3.2/tools/clang/lib/Sema/SemaLookup.cpp:2458
#4 0x000000000143b557 in TryConstructorInitialization (S=..., Entity=..., Kind=..., Args=0x2b2b120, NumArgs=2, DestType=..., Sequence=..., InitListSyntax=false)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaInit.cpp:2846
#5 0x000000000143f4a4 in clang::InitializationSequence::InitializationSequence (this=0x7fffffff9b20, S=..., Entity=..., Kind=..., Args=0x2b2b120, NumArgs=2)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaInit.cpp:4138
#6 0x00000000012f5e1a in clang::Sema::BuildMemberInitializer (this=0x2af0cb0, Member=0x2b2b138, Init=0x2b2b0f8, IdLoc=...)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaDeclCXX.cpp:2345
#7 0x00000000015ad440 in clang::Sema::InstantiateMemInitializers (this=0x2af0cb0, New=0x2ad5af0, Tmpl=0x2af5fc8, TemplateArgs=...)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:3116
#8 0x00000000015ac3a7 in clang::Sema::InstantiateFunctionDefinition (this=0x2af0cb0, PointOfInstantiation=..., Function=0x2ad5af0, Recursive=true, DefinitionRequired=false)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:2823
#9 0x00000000015aee72 in clang::Sema::PerformPendingInstantiations (this=0x2af0cb0, LocalOnly=false)
     at .../llvm-3.2/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:3630
...

Here is a simple test case that seems to reliably reproduce a SIGSEGV for me. This is what was used to produce the above back trace.
   #include <string>
   void f() {
     std::string s;
   }

So, anyone know if this call chain does represent an additional bug? Or are the comments provided for Sema::getCurScope() perhaps a little too strong?

Tom.

Sema-CurScope-init.patch (508 Bytes)

This email describes a SIGSEGV I’m experiencing with Clang 3.2 when calling Sema::PerformPendingInstantiations(). A patch against latest SVN is attached which resolves the SIGSEGV. However, it appears that the call to Sema::PerformPendingInstantiations() is resulting in a call to Sema::getCurScope() which, according to its comments, should never be called during template instantiation. The purpose of this email is to:

  1. Request that the attached patch be applied to SVN. The patch is trivial - it just adds missing initialization of the Sema::CurScope pointer within the Sema constructor.

Thanks, patch committed as r181251. If you have any way of testing this without building an additional binary, I’d appreciate it!

  1. Clarify whether the eventual call into Sema::getCurScope() from within Sema::PerformPendingInstantiations() represents an additional bug which should be addressed.

Generally, yes, but getScopeForContext is always allowed to call getCurScope.

    This email describes a SIGSEGV I'm experiencing with Clang 3.2 when
    calling Sema::__PerformPendingInstantiations()__. A patch against
    latest SVN is attached which resolves the SIGSEGV. However, it
    appears that the call to Sema::__PerformPendingInstantiations() is
    resulting in a call to Sema::getCurScope() which, according to its
    comments, should never be called during template instantiation. The
    purpose of this email is to:

    1) Request that the attached patch be applied to SVN. The patch is
    trivial - it just adds missing initialization of the Sema::CurScope
    pointer within the Sema constructor.

Thanks, patch committed as r181251. If you have any way of testing this
without building an additional binary, I'd appreciate it!

I briefly tried a few different ways to tickle this gremlin, but didn't find a clang invocation that didn't create a Parser instance. I'll admit, I didn't look hard though.

    2) Clarify whether the eventual call into Sema::getCurScope() from
    within Sema::__PerformPendingInstantiations() represents an
    additional bug which should be addressed.

Generally, yes, but getScopeForContext is always allowed to call
getCurScope.

Excellent, thanks for the clarification!

Tom.