Skip to content

Commit 14ef26c

Browse files
StdVariantChecker: the variant template arguments are retrieved incorrectly when type aliases are involved, causing crashes and FPs/FNs
1 parent e6a800f commit 14ef26c

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ bool isStdVariant(const Type *Type) {
9090
static std::optional<ArrayRef<TemplateArgument>>
9191
getTemplateArgsFromVariant(const Type *VariantType) {
9292
const auto *TempSpecType = VariantType->getAs<TemplateSpecializationType>();
93+
while (TempSpecType && TempSpecType->isTypeAlias())
94+
TempSpecType =
95+
TempSpecType->getAliasedType()->getAs<TemplateSpecializationType>();
9396
if (!TempSpecType)
9497
return {};
9598

clang/test/Analysis/std-variant-checker.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,25 @@ void nonInlineFunctionCallPtr() {
361361
// Misc
362362
// ----------------------------------------------------------------------------//
363363

364-
using uintptr_t = unsigned long long;
365-
366364
void unknownVal() {
367365
// force the argument to be UnknownVal
368-
(void)std::get<int>(*(std::variant<int, float>*)(uintptr_t)3.14f); // no crash
366+
(void)std::get<int>(*(std::variant<int, float>*)(int)3.14f); // no crash
367+
}
368+
369+
template <typename T>
370+
using MyVariant = std::variant<int, float>;
371+
372+
void typeAlias() {
373+
MyVariant<bool> v;
374+
375+
(void)std::get<int>(v); // no-warning
376+
}
377+
378+
template <template<typename> typename Container>
379+
using MySpecialVariant = std::variant<int, float>;
380+
381+
void complexTypeAlias() {
382+
MySpecialVariant<std::vector> v;
383+
384+
(void)std::get<int>(v); // no crash
369385
}

0 commit comments

Comments
 (0)