ilya-biryukov created this revision. ilya-biryukov added a reviewer: kadircet. Herald added a project: All. ilya-biryukov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Currently, Clang stores `nullptr` in the parameter lists inside `FunctionProtoTypeLoc` if `__fp16` is used without pointer qualifiers. Any code path that calls `Declarator::setInvalidType()` before `GetFullTypeForDeclarator` will lead to the same problem downstream. The relevant code is: cpp if (D.isInvalidType()) return Context.getTrivialTypeSourceInfo(T); return GetTypeSourceInfoForDeclarator(state, T, TInfo); `GetTypeSourceInfoForDeclarator` sets the parameter `Decl`, but we can't call it when `isInvalidType() == true` as this causes other assertion failures that seem harder to fix. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D146426 Files: clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaLambda.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaCXX/crash-params.cpp Index: clang/test/SemaCXX/crash-params.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/crash-params.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template <bool> +int foo() { + auto x = [&](__fp16) { return 0; }; // expected-error {{parameters cannot have __fp16 type}} + return 0; +} + +int bar() { return foo<true>(); } Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1343,7 +1343,7 @@ CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->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. Index: clang/lib/Sema/SemaLambda.cpp =================================================================== --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -966,8 +966,11 @@ 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); Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -1721,6 +1721,8 @@ 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, Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -15879,6 +15879,10 @@ 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.
Index: clang/test/SemaCXX/crash-params.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/crash-params.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template <bool> +int foo() { + auto x = [&](__fp16) { return 0; }; // expected-error {{parameters cannot have __fp16 type}} + return 0; +} + +int bar() { return foo<true>(); } Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1343,7 +1343,7 @@ CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->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. Index: clang/lib/Sema/SemaLambda.cpp =================================================================== --- clang/lib/Sema/SemaLambda.cpp +++ clang/lib/Sema/SemaLambda.cpp @@ -966,8 +966,11 @@ 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); Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -1721,6 +1721,8 @@ 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, Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -15879,6 +15879,10 @@ 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits