[cfe-dev] SIGSEGV in call to Sema::PerformPendingInstantiations() in Clang 3.2

Tom Honermann thonermann at coverity.com
Mon May 6 14:07:20 PDT 2013


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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Sema-CurScope-init.patch
Type: text/x-patch
Size: 508 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130506/6ad5a7a7/attachment.bin>


More information about the cfe-dev mailing list