[clang] [Clang] Fix crash on non-parameter NTTP arguments during partial ordering (PR #231599)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 13 10:49:47 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Emmanuel Antonio (EmmanuelAC1)
<details>
<summary>Changes</summary>
0b128824e723 (#<!-- -->224291) added a CWG2900 check in Sema::CheckTemplateArgument that calls isUndeducedAuto(getTypeOfConstantTemplateParameter(Arg), true). When Arg does not name a constant template parameter (for example, when checking a partial specialization argument such as 0, an enum value, nullptr, or a variable against an auto NTTP), getTypeOfConstantTemplateParameter returns a null QualType, which isUndeducedAuto immediately dereferenced.
Guard against a null QualType in isUndeducedAuto and check that Arg is an Expression before calling Arg.getAsExpr() in getTypeOfConstantTemplateParameter.
---
Full diff: https://github.com/llvm/llvm-project/pull/231599.diff
3 Files Affected:
- (modified) clang/lib/Sema/SemaTemplate.cpp (+2)
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+4-3)
- (modified) clang/test/SemaTemplate/temp_arg_nontype_arg_type.cpp (+16)
``````````diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ec1f8077893eb..5a61cb852d15e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5613,6 +5613,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
// parameter of type decltype(auto) ([temp.func.order]), the declaration
// is ill-formed.
auto isUndeducedAuto = [](QualType T, bool DecltypeAuto) {
+ if (T.isNull())
+ return false;
const AutoType *AT = T->getContainedAutoType();
return AT && AT->isDecltypeAuto() == DecltypeAuto &&
AT->getDeducedType().isNull();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f18097e358ca4..90724e1d01cb2 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -257,9 +257,10 @@ getNTTParameterFromExpr(const Expr *E, UnsignedOrNone Depth) {
}
QualType Sema::getTypeOfConstantTemplateParameter(const TemplateArgument &Arg) {
- if (NonTypeOrVarTemplateParmDecl NTTP =
- getNTTParameterFromExpr(Arg.getAsExpr(), std::nullopt))
- return NTTP.getType();
+ if (Arg.getKind() == TemplateArgument::Expression)
+ if (NonTypeOrVarTemplateParmDecl NTTP =
+ getNTTParameterFromExpr(Arg.getAsExpr(), std::nullopt))
+ return NTTP.getType();
return QualType();
}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_arg_type.cpp b/clang/test/SemaTemplate/temp_arg_nontype_arg_type.cpp
index 01290d91a2e84..e1d16a1d7689e 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_arg_type.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_arg_type.cpp
@@ -60,4 +60,20 @@ namespace ex7 {
short *g1(G<(j)> *ap) { return f(ap); }
long *g2(G<j> *ap) { return f(ap); }
}
+
+namespace partial_spec {
+ enum E { Val };
+ int global_var;
+
+ template <class T, auto V> struct A {};
+ template <class T> struct A<T, 0> {};
+ template <class T> struct A<T, Val> {};
+ template <class T> struct A<T, nullptr> {};
+
+ template <class T, auto... V> struct Pack {};
+ template <class T> struct Pack<T, 0, 1> {};
+
+ template <class T, const auto &V> struct Ref {};
+ template <class T> struct Ref<T, global_var> {};
+}
#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/231599
More information about the cfe-commits
mailing list