diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 02d1cb010db50..a3f2452b53d0c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -15879,6 +15879,10 @@ bool Sema::CheckParmsForFunctionDef(ArrayRef Parameters, bool CheckParameterNames) { bool HasInvalidParm = false; for (ParmVarDecl *Param : Parameters) { + if (!Param) { + HasInvalidParm = true; + continue; + } // C99 6.7.5.3p4: the parameters in a parameter type list in a // function declarator that is part of a function definition of // that function shall not have incomplete type. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 16e1071366b30..3dcc08f797811 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1712,6 +1712,8 @@ static bool CheckConstexprDestructorSubobjects(Sema &SemaRef, /// Check whether a function's parameter types are all literal types. If so, /// return true. If not, produce a suitable diagnostic and return false. +/// If any ParamDecl is null, return false without producing a diagnostic. +/// The code creating null parameters is responsible for producing a diagnostic. static bool CheckConstexprParameterTypes(Sema &SemaRef, const FunctionDecl *FD, Sema::CheckConstexprKind Kind) { @@ -1721,6 +1723,8 @@ static bool CheckConstexprParameterTypes(Sema &SemaRef, e = FT->param_type_end(); i != e; ++i, ++ArgIndex) { const ParmVarDecl *PD = FD->getParamDecl(ArgIndex); + if (!PD) + return false; SourceLocation ParamLoc = PD->getLocation(); if (CheckLiteralType(SemaRef, Kind, ParamLoc, *i, diag::err_constexpr_non_literal_param, ArgIndex + 1, diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 6a79a03e02fda..3a82c7b3e8285 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -966,8 +966,11 @@ void Sema::CompleteLambdaCallOperator( if (!Params.empty()) { CheckParmsForFunctionDef(Params, /*CheckParameterNames=*/false); Method->setParams(Params); - for (auto P : Method->parameters()) + for (auto P : Method->parameters()) { + if (!P) + continue; P->setOwningFunction(Method); + } } buildLambdaScopeReturnType(*this, LSI, Method, HasExplicitResultType); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index da66ffea46f49..b4649ce4c413c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1343,7 +1343,7 @@ namespace { CXXMethodDecl *MD = Result.getAs()->getCallOperator(); for (ParmVarDecl *PVD : MD->parameters()) { - if (!PVD->hasDefaultArg()) + if (!PVD || !PVD->hasDefaultArg()) continue; Expr *UninstExpr = PVD->getUninstantiatedDefaultArg(); // FIXME: Obtain the source location for the '=' token. diff --git a/clang/test/SemaCXX/GH61441.cpp b/clang/test/SemaCXX/GH61441.cpp new file mode 100644 index 0000000000000..73ff77515a7c4 --- /dev/null +++ b/clang/test/SemaCXX/GH61441.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -cl-std=clc++ -fblocks %s +// Checks Clang does not crash. We run in OpenCL mode to trigger block pointer +// crash. The __fp16 crash happens in standard mode too. + +template +int foo() { + auto x = [&](__fp16) { return 0; }; // expected-error {{not allowed}} + auto y = [&](void(^)(int)) { return 0; }; // expected-error {{not allowed}} + return 0; +} + +int bar() { return foo(); }