Skip to content

Commit

Permalink
[Sema] Fix a pair of crashes when generating exception specifiers wit…
Browse files Browse the repository at this point in the history
…h an

error'ed field for a template class' default ctor.

The two examples in the test would both cause a compiler assert when attempting
to calculate the exception specifier for the default constructor for the
template classes. The problem was that dependents of this function expect that
Field->getInClassInitializer (including canThrow) is not nullptr. However, if
the template's initializer has an error, exactly that situation happens.

This patch simply sets the field to be invalid.

Differential Revision: https://reviews.llvm.org/D37865

llvm-svn: 313569
  • Loading branch information
Erich Keane committed Sep 18, 2017
1 parent 283eae8 commit 0ac9524
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12436,7 +12436,8 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
assert(Pattern && "We must have set the Pattern!");
}

if (InstantiateInClassInitializer(Loc, Field, Pattern,
if (!Pattern->hasInClassInitializer() ||
InstantiateInClassInitializer(Loc, Field, Pattern,
getTemplateInstantiationArgs(Field))) {
// Don't diagnose this again.
Field->setInvalidDecl();
Expand Down
31 changes: 31 additions & 0 deletions clang/test/SemaCXX/init-expr-crash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11

// Test reproduces a pair of crashes that were caused by code attempting
// to materialize a default constructor's exception specifier.

template <class T> struct A {
static T tab[];

const int M = UNDEFINED; // expected-error {{use of undeclared identifier}}

int main()
{
A<char> a;

return 0;
}
};

template <class T> struct B {
static T tab[];

// expected-error@+1 {{invalid application of 'sizeof' to an incomplete type}}
const int N = sizeof(B<char>::tab) / sizeof(char);

int main()
{
B<char> b;

return 0;
}
};

0 comments on commit 0ac9524

Please sign in to comment.