llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) <details> <summary>Changes</summary> Those DecltypeExprs used to preserve RecoveryExprs which makes things complicated when we need to recover errors from a lambda expression. This patch stops that, as well as fixes some other error handlings. I don't think this is worth a release note entry - I just want to stop AI from messing around those things. Fixes https://github.com/llvm/llvm-project/issues/150733 Fixes https://github.com/llvm/llvm-project/issues/175713 Fixes https://github.com/llvm/llvm-project/issues/170185 --- Full diff: https://github.com/llvm/llvm-project/pull/233375.diff 8 Files Affected: - (modified) clang/lib/Parse/ParseTemplate.cpp (+2-1) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+4) - (modified) clang/lib/Sema/SemaLambda.cpp (+1-1) - (modified) clang/test/AST/ByteCode/records.cpp (+2-4) - (modified) clang/test/AST/ast-dump-expr-errors.cpp (+1-1) - (added) clang/test/SemaCXX/invalid-lambda.cpp (+58) - (removed) clang/test/SemaCXX/invalid-this-in-lambda.cpp (-4) - (modified) clang/test/SemaCXX/recovery-expr-type.cpp (+3-2) ``````````diff diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index ef6920fdc485c..ff4945f014db1 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1375,7 +1375,8 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { else ExprArg = ParseConstantExpressionInExprEvalContext( TypoCorrectionTypeBehavior::AllowBoth); - if (ExprArg.isInvalid() || !ExprArg.get()) { + if (ExprArg.isInvalid() || !ExprArg.get() || + ExprArg.get()->containsErrors()) { return ParsedTemplateArgument(); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d9bd060f7a0bf..2e717fe05a24e 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6930,6 +6930,10 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { ExpressionEvaluationContextRecord::EK_Decltype && "not in a decltype expression"); + // Give up here so we don't try to evaluate it later. + if (isa<RecoveryExpr>(E)) + return ExprError(); + ExprResult Result = CheckPlaceholderExpr(E); if (Result.isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 0c9a92cdd0c32..ed2423542d2af 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1488,7 +1488,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, const auto &FTI = ParamInfo.getFunctionTypeInfo(); LSI->ExplicitParams = FTI.getLParenLoc().isValid(); if (!FTIHasSingleVoidParameter(FTI)) { - Params.reserve(Params.size()); + Params.reserve(FTI.NumParams); for (unsigned I = 0; I < FTI.NumParams; ++I) { auto *Param = cast<ParmVarDecl>(FTI.Params[I].Param); Param->setScopeInfo(0, Params.size()); diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index ab79384a10476..4404eb7c6df23 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -2019,15 +2019,13 @@ namespace ErroneousVoidDecl { template <typename F, typename C, typename N1, typename N2> constexpr bool check(const C &c, N1 *n1, N2 *n2) { - decltype(f(c, n1, n2)) *chk{}; // both-error {{no matching function}} \ - // ref-note {{destroying object 'chk' whose lifetime has already ended}} + decltype(f(c, n1, n2)) *chk{}; // both-error {{no matching function}} return true; } template <int N> constexpr M<N> *bar() { return nullptr; } static_assert(check<S>([](int n) constexpr {}, bar<1u>(), bar<1u>())); // both-note {{in instantiation}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to}} + // both-error {{not an integral constant expression}} #endif } diff --git a/clang/test/AST/ast-dump-expr-errors.cpp b/clang/test/AST/ast-dump-expr-errors.cpp index 5661a41465eb6..1aad414a5c3d8 100644 --- a/clang/test/AST/ast-dump-expr-errors.cpp +++ b/clang/test/AST/ast-dump-expr-errors.cpp @@ -42,5 +42,5 @@ int d = static_cast<int>(bar() + 1); // Error type should result in an invalid decl. -// CHECK: -VarDecl {{.*}} invalid f 'decltype(<recovery-expr>(bar))' +// CHECK: -VarDecl {{.*}} invalid f 'int' decltype(bar()) f; diff --git a/clang/test/SemaCXX/invalid-lambda.cpp b/clang/test/SemaCXX/invalid-lambda.cpp new file mode 100644 index 0000000000000..a5ec348dcf439 --- /dev/null +++ b/clang/test/SemaCXX/invalid-lambda.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s + +decltype([]()->decltype(this) { }) a; // expected-error {{invalid use of 'this' outside of a non-static member function}} + +#if __cplusplus >= 202302L +namespace GH175173 { + +struct A { + void f(this A&) { + auto l = [](auto g, decltype(g(this))){}; + // expected-error@-1 {{invalid use of 'this'}} + } +}; + +struct B { + void f() { + auto l = [](int g, decltype(g(this))){}; + // expected-error@-1 {{called object type 'int'}} + } +}; + +} +#endif + +#if __cplusplus == 201103L + +namespace GH150733 { +auto L = [](auto a) { + // expected-error@-1 {{'auto' not allowed in lambda}} + auto M = [](decltype(a)) -> { + // expected-error@-1 {{expected a type}} + }; +}; +} + +#endif + +namespace GH170185 { + +struct Foo; // expected-note 2{{forward declaration}} + +template <Foo X> +// expected-error@-1 {{non-type template parameter has incomplete type}} +struct Arr; + +Foo f; // expected-error {{variable has incomplete type}} + +void foo() { + (void)[]() { + (void)[&](Arr<f>) { + + }; + }(); +} + +} diff --git a/clang/test/SemaCXX/invalid-this-in-lambda.cpp b/clang/test/SemaCXX/invalid-this-in-lambda.cpp deleted file mode 100644 index ae65bda025e23..0000000000000 --- a/clang/test/SemaCXX/invalid-this-in-lambda.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s - -decltype([]()->decltype(this) { }) a; // expected-error {{invalid use of 'this' outside of a non-static member function}} - diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp index 101d0155e3b98..7b6bd8d1699c5 100644 --- a/clang/test/SemaCXX/recovery-expr-type.cpp +++ b/clang/test/SemaCXX/recovery-expr-type.cpp @@ -195,8 +195,9 @@ using V = U<S<T>>; namespace GH202117 { template<template<decltype(foo())> typename T> struct S {}; // expected-error {{use of undeclared identifier 'foo'}} -template<int*> struct P; -S<P> s; +template<int*> struct P; // expected-error@-1 {{conversion from 'int' to 'int *' is not allowed}} +S<P> s; // expected-note {{template template argument has different template parameters}} +// expected-note@-3 {{previous template template parameter}} expected-note@-2 {{declared here}} } // namespace GH202117 namespace test17 { `````````` </details> https://github.com/llvm/llvm-project/pull/233375 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
