[cfe-commits] r143551 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/class-template-decl.cpp
Devang Patel
dpatel at apple.com
Fri Nov 4 10:34:37 PDT 2011
Doug,
This causes a crash in g++.dg/template/crash52.C
Please investigate.
Thanks!
-
Devang
UNREACHABLE executed at ASTContext.cpp:820!
0 clang 0x0000000102326955 PrintStackTrace(void*) + 53
1 clang 0x000000010232700b SignalHandler(int) + 379
2 libSystem.B.dylib 0x00007fff8a58f1ba _sigtramp + 26
3 libSystem.B.dylib 0x00007fff8a5331e1 szone_malloc_should_clear + 2070
4 clang 0x0000000102326cdb raise + 27
5 clang 0x0000000102326d9a abort + 26
6 clang 0x000000010230ada4 llvm::llvm_unreachable_internal(char const*, char const*, unsigned int) + 244
7 clang 0x0000000100f06278 clang::ASTContext::getTypeInfo(clang::Type const*) const + 120
8 clang 0x0000000100f2e8e9 clang::ASTContext::getTypeAlign(clang::Type const*) const + 25
9 clang 0x0000000100f06025 clang::ASTContext::getPreferredTypeAlign(clang::Type const*) const + 37
10 clang 0x0000000100f055ae clang::ASTContext::getDeclAlign(clang::Decl const*, bool) const + 1166
11 clang 0x00000001002b6977 clang::CodeGen::CodeGenFunction::EmitAutoVarAlloca(clang::VarDecl const&) + 215
12 clang 0x00000001002b4cbd clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(clang::VarDecl const&) + 45
13 clang 0x00000001002b4b91 clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) + 81
14 clang 0x00000001002b49f4 clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) + 212
15 clang 0x000000010038b84f clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) + 143
16 clang 0x0000000100385c92 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*) + 290
17 clang 0x0000000100385591 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) + 113
18 clang 0x000000010038b59f clang::CodeGen::CodeGenFunction::EmitCompoundStmt(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) + 447
19 clang 0x0000000100385c70 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*) + 256
20 clang 0x0000000100385591 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) + 113
21 clang 0x00000001003a62ac clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::CodeGen::FunctionArgList&) + 172
22 clang 0x00000001003a6751 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) + 1169
23 clang 0x00000001003b2bfd clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl) + 1277
24 clang 0x00000001003b011f clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl) + 623
25 clang 0x00000001003ad161 clang::CodeGen::CodeGenModule::EmitDeferred() + 561
26 clang 0x00000001003acd99 clang::CodeGen::CodeGenModule::Release() + 25
27 clang 0x00000001003fbea1 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) + 161
28 clang 0x00000001003a2fb3 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 163
29 clang 0x000000010040ea1c clang::ParseAST(clang::Sema&, bool) + 924
30 clang 0x0000000100083526 clang::ASTFrontendAction::ExecuteAction() + 278
31 clang 0x00000001003a0a7b clang::CodeGenAction::ExecuteAction() + 1291
32 clang 0x00000001000830e8 clang::FrontendAction::Execute() + 360
33 clang 0x000000010004c4a6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 1078
34 clang 0x000000010001a125 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1237
35 clang 0x0000000100001763 cc1_main(char const**, char const**, char const*, void*) + 1283
36 clang 0x000000010001328d main + 701
37 clang 0x0000000100001234 start + 52
On Nov 2, 2011, at 10:38 AM, Douglas Gregor wrote:
> Author: dgregor
> Date: Wed Nov 2 12:38:53 2011
> New Revision: 143551
>
> URL: http://llvm.org/viewvc/llvm-project?rev=143551&view=rev
> Log:
> Drastically simplify the mapping from the declaration corresponding to
> the injected-class-name of a class (or class template) to the
> declaration that results from substituting the given template
> arguments. Previously, we would actually perform a substitution into
> the injected-class-name type and then retrieve the resulting
> declaration. However, in certain, rare circumstances involving
> deeply-nested member templates, we would get the wrong substitution
> arguments.
>
> This new approach just matches up the declaration with a declaration
> that's part of the current context (or one of its parents), which will
> either be an instantiation (during template instantiation) or the
> declaration itself (during the definition of the template). This is
> both more efficient (we're avoiding a substitution) and more correct
> (we can't get the template arguments wrong in the member-template
> case).
>
> Fixes <rdar://problem/9676205>.
>
> Modified:
> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> cfe/trunk/test/SemaTemplate/class-template-decl.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=143551&r1=143550&r2=143551&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Nov 2 12:38:53 2011
> @@ -3148,75 +3148,49 @@
> if (!Record->isDependentContext())
> return D;
>
> - // If the RecordDecl is actually the injected-class-name or a
> - // "templated" declaration for a class template, class template
> - // partial specialization, or a member class of a class template,
> - // substitute into the injected-class-name of the class template
> - // or partial specialization to find the new DeclContext.
> - QualType T;
> + // Determine whether this record is the "templated" declaration describing
> + // a class template or class template partial specialization.
> ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
> -
> - if (ClassTemplate) {
> - T = ClassTemplate->getInjectedClassNameSpecialization();
> - } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
> - = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
> - ClassTemplate = PartialSpec->getSpecializedTemplate();
> -
> - // If we call SubstType with an InjectedClassNameType here we
> - // can end up in an infinite loop.
> - T = Context.getTypeDeclType(Record);
> - assert(isa<InjectedClassNameType>(T) &&
> - "type of partial specialization is not an InjectedClassNameType");
> - T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
> - }
> -
> - if (!T.isNull()) {
> - // Substitute into the injected-class-name to get the type
> - // corresponding to the instantiation we want, which may also be
> - // the current instantiation (if we're in a template
> - // definition). This substitution should never fail, since we
> - // know we can instantiate the injected-class-name or we
> - // wouldn't have gotten to the injected-class-name!
> -
> - // FIXME: Can we use the CurrentInstantiationScope to avoid this
> - // extra instantiation in the common case?
> - T = SubstType(T, TemplateArgs, Loc, DeclarationName());
> - assert(!T.isNull() && "Instantiation of injected-class-name cannot fail.");
> -
> - if (!T->isDependentType()) {
> - assert(T->isRecordType() && "Instantiation must produce a record type");
> - return T->getAs<RecordType>()->getDecl();
> + if (ClassTemplate)
> + ClassTemplate = ClassTemplate->getCanonicalDecl();
> + else if (ClassTemplatePartialSpecializationDecl *PartialSpec
> + = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))
> + ClassTemplate = PartialSpec->getSpecializedTemplate()->getCanonicalDecl();
> +
> + // Walk the current context to find either the record or an instantiation of
> + // it.
> + DeclContext *DC = CurContext;
> + while (!DC->isFileContext()) {
> + // If we're performing substitution while we're inside the template
> + // definition, we'll find our own context. We're done.
> + if (DC->Equals(Record))
> + return Record;
> +
> + if (CXXRecordDecl *InstRecord = dyn_cast<CXXRecordDecl>(DC)) {
> + // Check whether we're in the process of instantiating a class template
> + // specialization of the template we're mapping.
> + if (ClassTemplateSpecializationDecl *InstSpec
> + = dyn_cast<ClassTemplateSpecializationDecl>(InstRecord)){
> + ClassTemplateDecl *SpecTemplate = InstSpec->getSpecializedTemplate();
> + if (ClassTemplate && isInstantiationOf(ClassTemplate, SpecTemplate))
> + return InstRecord;
> + }
> +
> + // Check whether we're in the process of instantiating a member class.
> + if (isInstantiationOf(Record, InstRecord))
> + return InstRecord;
> }
> -
> - // We are performing "partial" template instantiation to create
> - // the member declarations for the members of a class template
> - // specialization. Therefore, D is actually referring to something
> - // in the current instantiation. Look through the current
> - // context, which contains actual instantiations, to find the
> - // instantiation of the "current instantiation" that D refers
> - // to.
> - bool SawNonDependentContext = false;
> - for (DeclContext *DC = CurContext; !DC->isFileContext();
> - DC = DC->getParent()) {
> - if (ClassTemplateSpecializationDecl *Spec
> - = dyn_cast<ClassTemplateSpecializationDecl>(DC))
> - if (isInstantiationOf(ClassTemplate,
> - Spec->getSpecializedTemplate()))
> - return Spec;
> -
> - if (!DC->isDependentContext())
> - SawNonDependentContext = true;
> +
> +
> + // Move to the outer template scope.
> + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) {
> + if (FD->getFriendObjectKind() && FD->getDeclContext()->isFileContext()){
> + DC = FD->getLexicalDeclContext();
> + continue;
> + }
> }
> -
> - // We're performing "instantiation" of a member of the current
> - // instantiation while we are type-checking the
> - // definition. Compute the declaration context and return that.
> - assert(!SawNonDependentContext &&
> - "No dependent context while instantiating record");
> - DeclContext *DC = computeDeclContext(T);
> - assert(DC &&
> - "Unable to find declaration for the current instantiation");
> - return cast<CXXRecordDecl>(DC);
> +
> + DC = DC->getParent();
> }
>
> // Fall through to deal with other dependent record types (e.g.,
>
> Modified: cfe/trunk/test/SemaTemplate/class-template-decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-decl.cpp?rev=143551&r1=143550&r2=143551&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaTemplate/class-template-decl.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/class-template-decl.cpp Wed Nov 2 12:38:53 2011
> @@ -75,3 +75,23 @@
> }
> }
>
> +namespace rdar9676205 {
> + template <unsigned, class _Tp> class tuple_element;
> +
> + template <class _T1, class _T2> class pair;
> +
> + template <class _T1, class _T2>
> + class tuple_element<0, pair<_T1, _T2> >
> + {
> + template <class _Tp>
> + struct X
> + {
> + template <class _Up, bool = X<_Up>::value>
> + struct Y
> + : public X<_Up>,
> + public Y<_Up>
> + { };
> + };
> + };
> +}
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20111104/70f99c50/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: crash52.C
Type: application/octet-stream
Size: 172 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20111104/70f99c50/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20111104/70f99c50/attachment-0001.html>
More information about the cfe-commits
mailing list