diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/Analysis/errno-stdlibraryfunctions.c | 30 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 12 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/messages.m | 3 | ||||
-rw-r--r-- | clang/test/Driver/gnustep-dispatch-method.m | 38 | ||||
-rw-r--r-- | clang/test/SemaCXX/crash-GH76228.cpp | 28 | ||||
-rw-r--r-- | clang/test/SemaCXX/paren-list-agg-init.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/template-instantiation.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unsafe-buffer-usage-warning-data-invocation.cpp | 131 |
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 |