Author: Adam Czachorowski Date: 2021-04-30T16:24:33+02:00 New Revision: fbfcfdbf6828b8d36f4ec0ff5f4eac11fb1411a5
URL: https://github.com/llvm/llvm-project/commit/fbfcfdbf6828b8d36f4ec0ff5f4eac11fb1411a5 DIFF: https://github.com/llvm/llvm-project/commit/fbfcfdbf6828b8d36f4ec0ff5f4eac11fb1411a5.diff LOG: [clang] Fix assert() crash when checking undeduced arg alignment There already was a check for undeduced and incomplete types, but it failed to trigger when outer type (SubstTemplateTypeParm in test) looked fine, but inner type was not. Differential Revision: https://reviews.llvm.org/D100667 Added: Modified: clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/recovery-expr-type.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7b6e0541aa4d7..38cda657bac8b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4540,8 +4540,7 @@ void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, // Find expected alignment, and the actual alignment of the passed object. // getTypeAlignInChars requires complete types - if (ParamTy->isIncompleteType() || ArgTy->isIncompleteType() || - ParamTy->isUndeducedType() || ArgTy->isUndeducedType()) + if (ParamTy->isIncompleteType() || ArgTy->isIncompleteType()) return; CharUnits ParamAlign = Context.getTypeAlignInChars(ParamTy); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e0f46a0ead40a..73d7675eb189f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -19662,8 +19662,10 @@ ExprResult Sema::CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, if (isSFINAEContext()) return ExprError(); - if (T.isNull() || !Context.getLangOpts().RecoveryASTType) + if (T.isNull() || T->isUndeducedType() || + !Context.getLangOpts().RecoveryASTType) // We don't know the concrete type, fallback to dependent type. T = Context.DependentTy; + return RecoveryExpr::Create(Context, T, Begin, End, SubExprs); } diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp index ed18b7f262cdc..8bdf83e9512fd 100644 --- a/clang/test/SemaCXX/recovery-expr-type.cpp +++ b/clang/test/SemaCXX/recovery-expr-type.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -o - %s -fsyntax-only -verify +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -o - %s -std=gnu++17 -fsyntax-only -verify namespace test0 { struct Indestructible { @@ -26,7 +26,7 @@ namespace test2 { void foo(); // expected-note 3{{requires 0 arguments}} void func() { // verify that "field has incomplete type" diagnostic is suppressed. - typeof(foo(42)) var; // expected-error {{no matching function}} + typeof(foo(42)) var; // expected-error {{no matching function}} \ // FIXME: suppress the "cannot initialize a variable" diagnostic. int a = foo(1); // expected-error {{no matching function}} \ @@ -116,3 +116,23 @@ int f(); // expected-note {{candidate}} template<typename T> const int k = f(T()); // expected-error {{no matching function}} static_assert(k<int> == 1, ""); // expected-note {{instantiation of}} } + +namespace test11 { +// Verify we do not assert()-fail here. +template <class T> void foo(T &t); +template <typename T> +void bar(T t) { + foo(t); +} + +template <typename T = void *> +struct S { // expected-note {{candidate}} + S(T t); // expected-note {{candidate}} + ~S(); +}; +template <typename T> S(T t) -> S<void *>; + +void baz() { + bar(S(123)); // expected-error {{no matching conversion}} +} +} // namespace test11 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits