aboutsummaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/errno-stdlibraryfunctions.c30
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp12
-rw-r--r--clang/test/CodeGenObjC/messages.m3
-rw-r--r--clang/test/Driver/gnustep-dispatch-method.m38
-rw-r--r--clang/test/SemaCXX/crash-GH76228.cpp28
-rw-r--r--clang/test/SemaCXX/paren-list-agg-init.cpp2
-rw-r--r--clang/test/SemaCXX/template-instantiation.cpp15
-rw-r--r--clang/test/SemaCXX/warn-unsafe-buffer-usage-warning-data-invocation.cpp131
8 files changed, 224 insertions, 35 deletions
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index dafda76..80e14c4 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -7,12 +7,9 @@
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
#include "Inputs/errno_var.h"
+#include "Inputs/std-c-library-functions-POSIX.h"
-typedef typeof(sizeof(int)) size_t;
-typedef __typeof(sizeof(int)) off_t;
-typedef size_t ssize_t;
-ssize_t send(int sockfd, const void *buf, size_t len, int flags);
-off_t lseek(int fildes, off_t offset, int whence);
+#define NULL ((void *) 0)
void clang_analyzer_warnIfReached();
void clang_analyzer_eval(int);
@@ -54,3 +51,26 @@ int errno_lseek(int fildes, off_t offset) {
}
return 0;
}
+
+void errno_mkstemp(char *template) {
+ int FD = mkstemp(template);
+ if (FD >= 0) {
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ close(FD);
+ } else {
+ clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ }
+}
+
+void errno_mkdtemp(char *template) {
+ char *Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 30ce6b4..3c500c2 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -376,6 +376,11 @@ namespace Specializations {
template<typename... Ts>
struct PrimaryClass<Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+ template<typename T, typename... Ts>
+ void PrimaryFunction();
+ template<typename T, typename... Ts>
+ void PrimaryFunction<Ts>(); // expected-error{{function template partial specialization is not allowed}}
+
#if __cplusplus >= 201402L
template<typename T, typename... Ts>
constexpr int PrimaryVar = 0;
@@ -392,6 +397,13 @@ namespace Specializations {
template<typename U>
struct InnerClass<U, Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+ template<typename... Us>
+ void InnerFunction();
+ template<>
+ void InnerFunction<Ts>(); // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}
+
+ friend void PrimaryFunction<Ts>(); // expected-error{{friend declaration contains unexpanded parameter pack 'Ts'}}
+
#if __cplusplus >= 201402L
template<typename... Us>
constexpr static int InnerVar = 0;
diff --git a/clang/test/CodeGenObjC/messages.m b/clang/test/CodeGenObjC/messages.m
index f93d35a..41f9d2f 100644
--- a/clang/test/CodeGenObjC/messages.m
+++ b/clang/test/CodeGenObjC/messages.m
@@ -1,7 +1,8 @@
// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC-NF
// RUN: %clang_cc1 -fobjc-runtime=gcc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-GNU
-// RUN: %clang_cc1 -fobjc-runtime=gnustep -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-GNU-NF
+// RUN: %clang_cc1 -fobjc-runtime=gnustep -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-GNU-NF
+// RUN: %clang_cc1 -fobjc-runtime=gnustep-2.2 -fobjc-dispatch-method=non-legacy -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC
typedef struct {
int x;
diff --git a/clang/test/Driver/gnustep-dispatch-method.m b/clang/test/Driver/gnustep-dispatch-method.m
new file mode 100644
index 0000000..6cd043f
--- /dev/null
+++ b/clang/test/Driver/gnustep-dispatch-method.m
@@ -0,0 +1,38 @@
+// DEFINE: %{triple} =
+// DEFINE: %{ver} = 1.6
+// DEFINE: %{prefix} = CHECK-MSGSEND
+// DEFINE: %{check} = %clang --target=%{triple} -fobjc-runtime=gnustep-%{ver} -### -c %s 2>&1 | FileCheck -check-prefix=%{prefix} %s
+
+// REDEFINE: %{ver} = 1.6
+// REDEFINE: %{triple} = i386-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{triple} = x86_64-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{triple} = arm-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{prefix} = CHECK-MSGLOOKUP
+// REDEFINE: %{triple} = aarch64-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{triple} = mips64-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{triple} = riscv64-unknown-freebsd
+// RUN: %{check}
+
+// REDEFINE: %{ver} = 1.9
+// REDEFINE: %{prefix} = CHECK-MSGSEND
+// REDEFINE: %{triple} = aarch64-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{triple} = mips64-unknown-freebsd
+// RUN: %{check}
+// REDEFINE: %{prefix} = CHECK-MSGLOOKUP
+// REDEFINE: %{triple} = riscv64-unknown-freebsd
+// RUN: %{check}
+
+// REDEFINE: %{ver} = 2.2
+// REDEFINE: %{prefix} = CHECK-MSGSEND
+// REDEFINE: %{triple} = riscv64-unknown-freebsd
+// RUN: %{check}
+
+
+// CHECK-MSGSEND: "-cc1"{{.*}} "-fobjc-dispatch-method=non-legacy"
+// CHECK-MSGLOOKUP-NOT: "-cc1"{{.*}} "-fobjc-dispatch-method=non-legacy"
diff --git a/clang/test/SemaCXX/crash-GH76228.cpp b/clang/test/SemaCXX/crash-GH76228.cpp
deleted file mode 100644
index 33a9395..0000000
--- a/clang/test/SemaCXX/crash-GH76228.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -verify %s
-// Check we don't crash on incomplete members and bases when handling parenthesized initialization.
-class incomplete; // expected-note@-0 3 {{forward declaration of 'incomplete'}}
-struct foo {
- int a;
- incomplete b;
- // expected-error@-1 {{incomplete type}}
-};
-foo a1(0);
-
-struct one_int {
- int a;
-};
-struct bar : one_int, incomplete {};
-// expected-error@-1 {{incomplete type}}
-bar a2(0);
-
-incomplete a3[3](1,2,3);
-// expected-error@-1 {{incomplete type}}
-
-struct qux : foo {
-};
-qux a4(0);
-
-struct fred {
- foo a[3];
-};
-fred a5(0);
diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp
index c1964a5..f60b20e 100644
--- a/clang/test/SemaCXX/paren-list-agg-init.cpp
+++ b/clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -289,7 +289,7 @@ int test() {
// used to crash
S a(0, 1);
S b(0);
- S c(0, 0, 1);
+ S c(0, 0, 1); // beforecxx20-warning {{aggregate initialization of type 'S' from a parenthesized list of values is a C++20 extension}}
S d {0, 1};
S e {0};
diff --git a/clang/test/SemaCXX/template-instantiation.cpp b/clang/test/SemaCXX/template-instantiation.cpp
new file mode 100644
index 0000000..8543af0
--- /dev/null
+++ b/clang/test/SemaCXX/template-instantiation.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+namespace GH76521 {
+
+template <typename T>
+void foo() {
+ auto l = []() __attribute__((preserve_most)) {};
+}
+
+void bar() {
+ foo<int>();
+}
+
+}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-warning-data-invocation.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-warning-data-invocation.cpp
new file mode 100644
index 0000000..79eb3bb
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-warning-data-invocation.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
+// RUN: -fsafe-buffer-usage-suggestions \
+// RUN: -fblocks -include %s -verify %s
+
+// RUN: %clang -x c++ -frtti -fsyntax-only -fblocks -include %s %s 2>&1 | FileCheck --allow-empty %s
+// RUN: %clang_cc1 -std=c++11 -fblocks -include %s %s 2>&1 | FileCheck --allow-empty %s
+// RUN: %clang_cc1 -std=c++20 -fblocks -include %s %s 2>&1 | FileCheck --allow-empty %s
+// CHECK-NOT: [-Wunsafe-buffer-usage]
+
+#ifndef INCLUDED
+#define INCLUDED
+#pragma clang system_header
+
+// no spanification warnings for system headers
+#else
+
+namespace std {
+ class type_info;
+ class bad_cast;
+ class bad_typeid;
+}
+using size_t = __typeof(sizeof(int));
+void *malloc(size_t);
+
+void foo(int v) {
+}
+
+void foo(int *p){}
+
+namespace std{
+ template <typename T> class span {
+
+ T *elements;
+
+ span(T *, unsigned){}
+
+ public:
+
+ constexpr span<T> subspan(size_t offset, size_t count) const {
+ return span<T> (elements+offset, count); // expected-warning{{unsafe pointer arithmetic}}
+ }
+
+ constexpr T* data() const noexcept {
+ return elements;
+ }
+
+
+ constexpr T* hello() const noexcept {
+ return elements;
+ }
+};
+
+ template <typename T> class span_duplicate {
+ span_duplicate(T *, unsigned){}
+
+ T array[10];
+
+ public:
+
+ T* data() {
+ return array;
+ }
+
+};
+}
+
+using namespace std;
+
+class A {
+ int a, b, c;
+};
+
+class B {
+ int a, b, c;
+};
+
+struct Base {
+ virtual ~Base() = default;
+};
+
+struct Derived: Base {
+ int d;
+};
+
+void cast_without_data(int *ptr) {
+ A *a = (A*) ptr;
+ float *p = (float*) ptr;
+}
+
+void warned_patterns(std::span<int> span_ptr, std::span<Base> base_span, span<int> span_without_qual) {
+ A *a1 = (A*)span_ptr.data(); // expected-warning{{unsafe invocation of span::data}}
+ a1 = (A*)span_ptr.data(); // expected-warning{{unsafe invocation of span::data}}
+
+ A *a2 = (A*) span_without_qual.data(); // expected-warning{{unsafe invocation of span::data}}
+
+ // TODO:: Should we warn when we cast from base to derived type?
+ Derived *b = dynamic_cast<Derived*> (base_span.data());// expected-warning{{unsafe invocation of span::data}}
+
+ // TODO:: This pattern is safe. We can add special handling for it, if we decide this
+ // is the recommended fixit for the unsafe invocations.
+ A *a3 = (A*)span_ptr.subspan(0, sizeof(A)).data(); // expected-warning{{unsafe invocation of span::data}}
+}
+
+void not_warned_patterns(std::span<A> span_ptr, std::span<Base> base_span) {
+ int *p = (int*) span_ptr.data(); // Cast to a smaller type
+
+ B *b = (B*) span_ptr.data(); // Cast to a type of same size.
+
+ p = (int*) span_ptr.data();
+ A *a = (A*) span_ptr.hello(); // Invoking other methods.
+}
+
+// We do not want to warn about other types
+void other_classes(std::span_duplicate<int> span_ptr) {
+ int *p;
+ A *a = (A*)span_ptr.data();
+ a = (A*)span_ptr.data();
+}
+
+// Potential source for false negatives
+
+A false_negatives(std::span<int> span_pt, span<A> span_A) {
+ int *ptr = span_pt.data();
+
+ A *a1 = (A*)ptr; //TODO: We want to warn here eventually.
+
+ A *a2= span_A.data();
+ return *a2; // TODO: Can cause OOB if span_pt is empty
+
+}
+#endif