Author: Adam Czachorowski Date: 2021-08-03T11:52:52+02:00 New Revision: 08128fe7059e20b3f97ae5abbdeff2e6f6c711ed
URL: https://github.com/llvm/llvm-project/commit/08128fe7059e20b3f97ae5abbdeff2e6f6c711ed DIFF: https://github.com/llvm/llvm-project/commit/08128fe7059e20b3f97ae5abbdeff2e6f6c711ed.diff LOG: [clang] Make member var invalid when static initializer is invalid. Previously we would show an error, but keep the member, and also the CXXRrecordDecl, valid. This could lead to crashes when attempting to access the record layout or size. Differential Revision: https://reviews.llvm.org/D105478 Added: clang/test/AST/ast-dump-undeduced-expr.cpp Modified: clang/lib/Parse/ParseDeclCXX.cpp clang/test/SemaCXX/crash-auto-36064.cpp clang/test/SemaCXX/cxx11-crashes.cpp Removed: ################################################################################ diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index ca5c013a51fe0..760600a3ea3ca 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2989,9 +2989,11 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, ExprResult Init = ParseCXXMemberInitializer( ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); - if (Init.isInvalid()) + if (Init.isInvalid()) { + if (ThisDecl) + Actions.ActOnUninitializedDecl(ThisDecl); SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); - else if (ThisDecl) + } else if (ThisDecl) Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid()); } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) // No initializer. diff --git a/clang/test/AST/ast-dump-undeduced-expr.cpp b/clang/test/AST/ast-dump-undeduced-expr.cpp new file mode 100644 index 0000000000000..d404db9285974 --- /dev/null +++ b/clang/test/AST/ast-dump-undeduced-expr.cpp @@ -0,0 +1,7 @@ +// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck %s + +struct Foo { + static constexpr auto Bar = ; +}; + +// CHECK: -VarDecl {{.*}} invalid Bar 'const auto' static constexpr diff --git a/clang/test/SemaCXX/crash-auto-36064.cpp b/clang/test/SemaCXX/crash-auto-36064.cpp index 5678cd8b730b8..a34e5eea51cb0 100644 --- a/clang/test/SemaCXX/crash-auto-36064.cpp +++ b/clang/test/SemaCXX/crash-auto-36064.cpp @@ -1,8 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -template <typename A, decltype(new A)> // expected-error{{new expression for type 'auto' requires a constructor argument}} +template <typename A, decltype(new A)> struct b; struct d { static auto c = ; // expected-error{{expected expression}} + // expected-error@-1 {{declaration of variable 'c' with deduced type 'auto' requires an initializer}} + decltype(b<decltype(c), int>); // expected-error{{expected '(' for function-style cast or type construction}} - // expected-note@-1{{while substituting prior template arguments into non-type template parameter [with A = auto]}} }; diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp index d60782df35f45..e63a9be956942 100644 --- a/clang/test/SemaCXX/cxx11-crashes.cpp +++ b/clang/test/SemaCXX/cxx11-crashes.cpp @@ -104,3 +104,22 @@ namespace pr29091 { bool baz() { return __has_nothrow_constructor(B); } bool qux() { return __has_nothrow_copy(B); } } + +namespace undeduced_field { +template<class T> +struct Foo { + typedef T type; +}; + +struct Bar { + Bar(); + // The missing expression makes A undeduced. + static constexpr auto A = ; // expected-error {{expected expression}} + // expected-error@-1 {{declaration of variable 'A' with deduced type 'const auto' requires an initializer}} + + Foo<decltype(A)>::type B; // The type of B is also undeduced (wrapped in Elaborated). +}; + +// This used to crash when trying to get the layout of B. +Bar x; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits