Hi Haojian, I noticed that after your change, the compiler is now giving an error when trying to create a vector of >= 1024 elements when previously it worked, and gcc has no problem with the same code. Is that intentional? I have put the details in PR45387, can you take a look?
Douglas Yung -----Original Message----- From: cfe-commits <cfe-commits-boun...@lists.llvm.org> On Behalf Of Haojian Wu via cfe-commits Sent: Monday, March 30, 2020 5:57 To: cfe-commits@lists.llvm.org Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). Author: Haojian Wu Date: 2020-03-30T14:56:33+02:00 New Revision: 6f428e09fbe8ce7e3510ae024031a5fc19653483 URL: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483 DIFF: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483.diff LOG: [AST] Fix crashes on decltype(recovery-expr). Summary: We mark these decls as invalid. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77037 Added: Modified: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp clang/unittests/Sema/CodeCompleteTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index 75c9aa1656b8..0b24bae6df9b 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -50,14 +50,16 @@ struct TypeDependenceScope { /// Whether this type is a variably-modified type (C99 6.7.5). VariablyModified = 8, - // FIXME: add Error bit. + /// Whether this type references an error, e.g. decltype(err-expression) + /// yields an error type. + Error = 16, None = 0, - All = 15, + All = 31, DependentInstantiation = Dependent | Instantiation, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) }; }; using TypeDependence = TypeDependenceScope::TypeDependence; @@ -147,6 +149,7 @@ class Dependence { return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | translate(V, Instantiation, TypeDependence::Instantiation) | translate(V, Dependent, TypeDependence::Dependent) | + translate(V, Error, TypeDependence::Error) | translate(V, VariablyModified, TypeDependence::VariablyModified); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 248fbcfba98e..5d2c035ea0fe 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2139,6 +2139,11 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { return static_cast<TypeDependence>(TypeBits.Dependence); } + /// Whether this type is an error type. + bool containsErrors() const { + return getDependence() & TypeDependence::Error; } + /// Whether this type is a dependent type, meaning that its definition /// somehow depends on a template parameter (C++ [temp.dep.type]). bool isDependentType() const { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 761fad9456be..4389c8777c6d 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3105,10 +3105,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { auto RunSignatureHelp = [&]() { ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); - assert(TypeRep && "invalid types should be handled before"); - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); + QualType PreferredType; + // ActOnTypeName might adjust DeclaratorInfo and return a null type even + // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on + // `new decltype(invalid) (^)`. + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, + ConstructorLParen); CalledSignatureHelp = true; return PreferredType; }; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 55ce028fb8c2..e128ebf31270 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1678,6 +1678,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; } + // FIXME: we want resulting declarations to be marked invalid, but + claiming // the type is invalid is too strong - e.g. it causes + ActOnTypeName to return // a null type. + if (Result->containsErrors()) + declarator.setInvalidType(); + if (S.getLangOpts().OpenCL && S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) declarator.setInvalidType(true); diff --git a/clang/test/AST/ast-dump-expr-errors.cpp b/clang/test/AST/ast-dump-expr-errors.cpp index e623fad04f4c..9334b73a4354 100644 --- a/clang/test/AST/ast-dump-expr-errors.cpp +++ b/clang/test/AST/ast-dump-expr-errors.cpp @@ -42,5 +42,9 @@ int d = static_cast<int>(bar() + 1); // FIXME: store initializer even when 'auto' could not be deduced. // Expressions with errors currently do not keep initializers around. -// CHECK: `-VarDecl {{.*}} invalid e 'auto' +// CHECK: -VarDecl {{.*}} invalid e 'auto' auto e = bar(); + +// Error type should result in an invalid decl. +// CHECK: -VarDecl {{.*}} invalid f 'decltype(<recovery-expr>(bar))' +decltype(bar()) f; diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp index 5475157e936e..544979980fc9 100644 --- a/clang/test/Sema/invalid-member.cpp +++ b/clang/test/Sema/invalid-member.cpp @@ -1,7 +1,15 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -void foo(); // expected-note {{requires 0 arguments}} +// RUN: %clang_cc1 -verify -fsyntax-only -fno-recovery-ast %s // RUN: +%clang_cc1 -verify -fsyntax-only -frecovery-ast %s + +void foo(); // expected-note 2{{requires 0 arguments}} class X { decltype(foo(42)) invalid; // expected-error {{no matching function}} }; // Should be able to evaluate sizeof without crashing. static_assert(sizeof(X) == 1, "No valid members"); + +class Y { + typeof(foo(42)) invalid; // expected-error {{no matching function}} +}; // Should be able to evaluate sizeof without crashing. +static_assert(sizeof(Y) == 1, "No valid members"); diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp b/clang/unittests/Sema/CodeCompleteTest.cpp index a9441a679cac..d8b303d77bb9 100644 --- a/clang/unittests/Sema/CodeCompleteTest.cpp +++ b/clang/unittests/Sema/CodeCompleteTest.cpp @@ -486,7 +486,10 @@ TEST(PreferredTypeTest, NoCrashOnInvalidTypes) { StringRef Code = R"cpp( auto x = decltype(&1)(^); auto y = new decltype(&1)(^); + // GNU decimal type extension is not supported in clang. + auto z = new _Decimal128(^); )cpp"; EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE")); } + } // namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits