From acf3bdc283ecf6e2c3a85a391a24becc4814b8b8 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Sat, 18 Jul 2020 20:44:06 +0100 Subject: [PATCH] [clang][NFC] Tests showing the problems with some uses of NamedDecl::getDeclName in diagnostics, SemaOverload.cpp+SemaStmt.cpp part --- .../CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp | 6 ++++ clang/test/Sema/return-non-void.c | 5 ++++ clang/test/SemaCXX/constant-expression-cxx11.cpp | 5 ++++ clang/test/SemaCXX/consteval-return-void.cpp | 10 +++++++ clang/test/SemaCXX/return-void.cpp | 26 ++++++++++++++++++ clang/test/SemaCXX/return.cpp | 12 +++++++- .../warn-pure-virtual-call-from-ctor-dtor.cpp | 32 ++++++++++++++++++++++ clang/test/SemaCXX/warn-pure-virtual-kext.cpp | 12 ++++++++ clang/test/SemaObjC/method-return-void.m | 9 ++++++ 9 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 clang/test/Sema/return-non-void.c create mode 100644 clang/test/SemaCXX/consteval-return-void.cpp create mode 100644 clang/test/SemaCXX/return-void.cpp create mode 100644 clang/test/SemaObjC/method-return-void.m diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp index 59cac36..0d4d34a 100644 --- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp @@ -7,6 +7,12 @@ void a2 [[noreturn]] () { return; // expected-warning {{function 'a2' declared 'noreturn' should not return}} } +template void a3 [[noreturn]] () {} +template <> void a3 () { return; } // expected-warning {{function 'a3' declared 'noreturn' should not return}} + +template void a4 [[noreturn]] () { return; } // expected-warning 2{{function 'a4' declared 'noreturn' should not return}} +void a4_test() { a4(); } // expected-note {{in instantiation of function template specialization 'a4' requested here}} + [[noreturn, noreturn]] void b() { throw 0; } // expected-error {{attribute 'noreturn' cannot appear multiple times in an attribute specifier}} [[noreturn]] [[noreturn]] void b2() { throw 0; } // ok diff --git a/clang/test/Sema/return-non-void.c b/clang/test/Sema/return-non-void.c new file mode 100644 index 0000000..f1ee372 --- /dev/null +++ b/clang/test/Sema/return-non-void.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -Wreturn-type -std=c99 -fsyntax-only -verify=c99 %s +// RUN: %clang_cc1 -Wreturn-type -std=c90 -fsyntax-only -verify=c90 %s + +int foo(void) { return; } // c99-error {{non-void function 'foo' should return a value}} + // c90-error@-1 {{non-void function 'foo' should return a value}} diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index b69bcb2..7ff260c 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -2167,6 +2167,11 @@ namespace PR21786 { namespace PR21859 { constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}} constexpr int Var = Fun(); + + template constexpr int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} + template constexpr int FunT2() { return 0; } + template <> constexpr int FunT2() { return 0; } + template <> constexpr int FunT2() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} } struct InvalidRedef { diff --git a/clang/test/SemaCXX/consteval-return-void.cpp b/clang/test/SemaCXX/consteval-return-void.cpp new file mode 100644 index 0000000..a5207f4 --- /dev/null +++ b/clang/test/SemaCXX/consteval-return-void.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +consteval int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}} + +// FIXME: The diagnostic is wrong; should be "consteval". + +template consteval int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} +template consteval int FunT2() { return 0; } +template <> consteval int FunT2() { return 0; } +template <> consteval int FunT2() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} diff --git a/clang/test/SemaCXX/return-void.cpp b/clang/test/SemaCXX/return-void.cpp new file mode 100644 index 0000000..b3aa203 --- /dev/null +++ b/clang/test/SemaCXX/return-void.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify + +void f1() { return {1,2}; } // expected-error {{void function 'f1' must not return a value}} + +template void f2() { return {1,2}; } // expected-error {{void function 'f2' must not return a value}} + +template <> void f2() { return {1,2}; } // expected-error {{void function 'f2' must not return a value}} + +void test_f2() { + f2(); + f2(); +} + +struct S { + void f3() { return {1,2}; } // expected-error {{void function 'f3' must not return a value}} + S() { return {1,2}; } // expected-error {{constructor 'S' must not return a value}} + ~S() { return {1,2}; } // expected-error {{destructor '~S' must not return a value}} +}; + +template struct ST { + void f4() { return {1,2}; } // expected-error {{void function 'f4' must not return a value}} + ST() { return {1,2}; } // expected-error {{constructor 'ST' must not return a value}} + ~ST() { return {1,2}; } // expected-error {{destructor '~ST' must not return a value}} +}; + +ST st; diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp index db28924..1550d00 100644 --- a/clang/test/SemaCXX/return.cpp +++ b/clang/test/SemaCXX/return.cpp @@ -108,9 +108,19 @@ namespace return_has_expr { namespace ctor_returns_void { void f() {} struct S { - S() { return f(); }; // expected-error {{constructor 'S' must not return void expression}} + S() { return f(); } // expected-error {{constructor 'S' must not return void expression}} ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}} }; + + template struct ST { + ST() { return f(); } // expected-error {{constructor 'ST' must not return void expression}} + // expected-error@-1 {{constructor 'ST' must not return void expression}} + ~ST() { return f(); } // expected-error {{destructor '~ST' must not return void expression}} + // expected-error@-1 {{destructor '~ST' must not return void expression}} + }; + + ST st; // expected-note {{in instantiation of member function 'ctor_returns_void::ST::ST'}} + // expected-note@-1 {{in instantiation of member function 'ctor_returns_void::ST::~ST'}} } void cxx_unresolved_expr() { diff --git a/clang/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp b/clang/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp index 3312b56..789935e 100644 --- a/clang/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp +++ b/clang/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp @@ -20,3 +20,35 @@ struct C { C::f(); } }; + +template struct TA { + TA() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'TA'}} + ~TA() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the destructor of 'TA'}} + + virtual void f() = 0; // expected-note 2{{'f' declared here}} +}; + +template <> struct TA { + TA() { f(); } + ~TA() { f(); } + void f(); +}; + +template <> struct TA { + TA() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'TA'}} + ~TA() { f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the destructor of 'TA'}} + virtual void f() = 0; // expected-note 2{{'f' declared here}} +}; + +struct TB : TA { // expected-note {{in instantiation of member function 'TA::TA' requested here}} + void f() override; // expected-note@-1 {{in instantiation of member function 'TA::~TA' requested here}} +}; +TB tb; + +struct TC : TA {}; // ok +TC tc; // ok + +struct TD : TA { + void f() override; +}; +TD td; diff --git a/clang/test/SemaCXX/warn-pure-virtual-kext.cpp b/clang/test/SemaCXX/warn-pure-virtual-kext.cpp index e681a02..8431e202 100644 --- a/clang/test/SemaCXX/warn-pure-virtual-kext.cpp +++ b/clang/test/SemaCXX/warn-pure-virtual-kext.cpp @@ -6,3 +6,15 @@ struct A { A::f(); // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'A'}} // expected-note {{qualified call to 'A'::'f' is treated as a virtual call to 'f' due to -fapple-kext}} } }; + +template struct TA { + virtual void f() = 0; // expected-note {{'f' declared here}} + + TA() { TA::f(); } // expected-warning {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'TA'}} // expected-note {{qualified call to 'TA'::'f' is treated as a virtual call to 'f' due to -fapple-kext}} +}; + +struct B : TA { // expected-note {{in instantiation of member function 'TA::TA' requested here}} + void f() override; +}; + +B b; diff --git a/clang/test/SemaObjC/method-return-void.m b/clang/test/SemaObjC/method-return-void.m new file mode 100644 index 0000000..850c81b --- /dev/null +++ b/clang/test/SemaObjC/method-return-void.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -Wmethod-signatures -fsyntax-only -verify -Wno-objc-root-class %s + +@interface Test +- (int)foo; +@end + +@implementation Test +- (int)foo { return; } // expected-error {{non-void method 'foo' should return a value}} +@end -- 2.7.4