On 01/06/2013 06:49 PM, Enea Zaffanella wrote:
Hello.
clang is crashing, in debug mode, on invalid code such as the following
(distilled from a gcc testcase):
======================
template <class>
void foo() {
(struct S {}*) 0;
}
void bar() {
foo<int>();
}
======================
$ clang++ -c bug.cc
bug.cc:3:11: error: 'S' can not be defined in a type specifier
(struct S {}*) 0;
^
clang: SemaTemplateInstantiate.cpp:2691:
llvm::PointerUnion<clang::Decl*, llvm::SmallVector<clang::Decl*, 4u>*>*
clang::LocalInstantiationScope::findInstantiationOf(const clang::Decl*):
Assertion `isa<LabelDecl>(D) && "declaration not instantiated in this
scope"' failed.
The problem seems to be that, after emitting the error diagnostics for
the template, the code is kept as valid code in the AST; hence it later
causes a crash when instantiating the template.
Please find attached a patch fixing the crash mentioned above.
The patch includes minor changes to 3 tests, where (as expected) we no
longer get further diagnostics on the code already marked as invalid.
OK to commit?
Enea.
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp (revision 171384)
+++ lib/Sema/SemaType.cpp (working copy)
@@ -1996,6 +1996,7 @@
SemaRef.Diag(OwnedTagDecl->getLocation(),
diag::err_type_defined_in_alias_template)
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
+ D.setInvalidType(true);
break;
case Declarator::TypeNameContext:
case Declarator::TemplateParamContext:
@@ -2006,6 +2007,7 @@
SemaRef.Diag(OwnedTagDecl->getLocation(),
diag::err_type_defined_in_type_specifier)
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
+ D.setInvalidType(true);
break;
case Declarator::PrototypeContext:
case Declarator::ObjCParameterContext:
@@ -2016,6 +2018,7 @@
SemaRef.Diag(OwnedTagDecl->getLocation(),
diag::err_type_defined_in_param_type)
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
+ D.setInvalidType(true);
break;
case Declarator::ConditionContext:
// C++ 6.4p2:
@@ -2023,6 +2026,7 @@
// a new class or enumeration.
SemaRef.Diag(OwnedTagDecl->getLocation(),
diag::err_type_defined_in_condition);
+ D.setInvalidType(true);
break;
}
}
Index: test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
===================================================================
--- test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp (revision 171384)
+++ test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp (working copy)
@@ -1,10 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
struct A { };
-A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} \
-// expected-error{{out-of-line definition}}
-void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} \
-// expected-error{{out-of-line definition}}
+A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}}
+void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}}
enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \
// expected-error{{out-of-line definition}}
Index: test/SemaCXX/alias-template.cpp
===================================================================
--- test/SemaCXX/alias-template.cpp (revision 171384)
+++ test/SemaCXX/alias-template.cpp (working copy)
@@ -105,9 +105,7 @@
template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}}
template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}}
template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}}
- template<typename Z> using V = struct V { int n; }; // expected-error {{redefinition of 'V' as different kind of symbol}} \
- expected-error {{'TagName::V' can not be defined in a type alias template}} \
- expected-note {{previous definition is here}}
+ template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' can not be defined in a type alias template}}
}
namespace StdExample {
Index: test/SemaCXX/condition.cpp
===================================================================
--- test/SemaCXX/condition.cpp (revision 171384)
+++ test/SemaCXX/condition.cpp (working copy)
@@ -19,7 +19,7 @@
while (struct NewS *x=0) ;
while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}}
while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}}
- switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
+ switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} \
// expected-warning{{enumeration value 'E' not handled in switch}} expected-warning {{switch statement has empty body}} \
// expected-note{{put the semicolon on a separate line}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits