[clang] [analyzer] Add std::variant checker (PR #66481)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 21 03:40:26 PDT 2023
================
@@ -0,0 +1,349 @@
+// RUN: %clang %s -std=c++17 -Xclang -verify --analyze \
+// RUN: -Xclang -analyzer-checker=core \
+// RUN: -Xclang -analyzer-checker=debug.ExprInspection \
+// RUN: -Xclang -analyzer-checker=core,alpha.core.StdVariant
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+class Foo{};
+
+void clang_analyzer_warnIfReached();
+void clang_analyzer_eval(int);
+
+//helper functions
+void changeVariantType(std::variant<int, char> &v) {
+ v = 25;
+}
+
+void changesToInt(std::variant<int, char> &v);
+void changesToInt(std::variant<int, char> *v);
+
+void cannotChangePtr(const std::variant<int, char> &v);
+void cannotChangePtr(const std::variant<int, char> *v);
+
+char getUnknownChar();
+
+void swap(std::variant<int, char> &v1, std::variant<int, char> &v2) {
+ std::variant<int, char> tmp = v1;
+ v1 = v2;
+ v2 = tmp;
+}
+
+void cantDo(const std::variant<int, char>& v) {
+ std::variant<int, char> vtmp = v;
+ vtmp = 5;
+ int a = std::get<int> (vtmp);
+ (void*) a;
+}
+
+void changeVariantPtr(std::variant<int, char> *v) {
+ *v = 'c';
+}
+
+using var_t = std::variant<int, char>;
+using var_tt = var_t;
+using int_t = int;
+using char_t = char;
+
+
+//----------------------------------------------------------------------------//
+// std::get
+//----------------------------------------------------------------------------//
+void stdGetType() {
+ std::variant<int, char> v = 25;
+ int a = std::get<int>(v);
+ char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int' not a 'char'}}
+ (void*)a;
+ (void*)c;
+}
+
+void stdGetPointer() {
+ int *p = new int;
+ std::variant<int*, char> v = p;
+ int *a = std::get<int*>(v);
+ char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int *' not a 'char'}}
+ (void**)a;
+ (void*)c;
+ delete p;
+}
+
+void stdGetObject() {
+ std::variant<int, char, Foo> v = Foo{};
+ Foo f = std::get<Foo>(v);
+ int i = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'Foo' not an 'int'}}
+ (void*)i;
+}
+
+void stdGetPointerAndPointee() {
+ int a = 5;
+ std::variant<int, int*> v = &a;
+ int *b = std::get<int*>(v);
+ int c = std::get<int>(v); // expected-warning {{std::variant 'v' held an 'int *' not an 'int'}}
+ (void*)c;
+ (void**)b;
+}
+
+void variantHoldingVariant() {
+ std::variant<std::variant<int, char>, std::variant<char, int>> v = std::variant<int,char>(25);
+ std::variant<int, char> v1 = std::get<std::variant<int,char>>(v);
+ std::variant<char, int> v2 = std::get<std::variant<char,int>>(v); // expected-warning {{std::variant 'v' held a 'std::variant<int, char>' not a 'class std::variant<char, int>'}}
+}
----------------
DonatNagyE wrote:
Beautiful testcase :1st_place_medal:
Demonstrates the full glory of the type system...
https://github.com/llvm/llvm-project/pull/66481
More information about the cfe-commits
mailing list