tigerleapgorge created this revision. I am continuing to make Lit tests C++11 compatible. This patch contains 3 tests, previously in review https://reviews.llvm.org/D21626. First two tests involve printf format attributes. The third test involve thread safety attribute. Here are the descriptions for each test.
test/SemaCXX/format-strings.cpp This test verifies format specifiers. This test contains 2 parts. Part 1. C++11 added Scanf floating-point format specifier “a”. http://en.cppreference.com/w/c/io/fscanf The Scanf format specifier “%as” expects type “float *”. However, the actual argument is type “char **”. Change in diagnostics. C++98: warning: 'a' length modifier is not supported by ISO C [-Wformat-non-iso] C++11: warning: format specifies type 'float *' but the argument has type 'char **' [-Wformat] Part 2. Function test_null_format() expects a const char * as its first formal argument, but is instead given a Boolean literal as its first actual argument. Type conversion from const bool to const char * is a Warning in C++98, but an Error in C++11. Change in diagnostics. C++98: warning: initialization of pointer of type 'const char *' to null from a constant boolean expression [-Wbool-conversion] C++11: error: no matching function for call to 'test_null_format' note: candidate function not viable: no known conversion from 'bool' to 'const char *' for 1st argument test/SemaCXX/printf-cstr.cpp This tests verifies type mismatches between printf format specifiers and the type of the actual arguments. This test contains 3 types of diagnostic changes. Diagnostics changed for mismatch between “%s” and actual arguments of non-POD class instance. In C++98, non-POD objects are not allowed as variadic arguments. In C++11, non-POD is allowed (5.2.2/7). However, since the format specifier %s expects a char pointer not an object, Clang will issue a Warning on that. If the class has a c_str() method, Clang will issue a accompanying Note to prompt the use to invoke it. Type 1: A class object that has a c_str() method is passed in. In C++98, Clang issues a Warning and an accompanying Note. In C++11, Clang issues a Warning. Expect the following change in diagnostics. (3 instances) C++98: warning: cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *' [-Wnon-pod-varargs] note: did you mean to call the c_str() method? C++11: warning: format specifies type 'char *' but the argument has type 'HasCStr' [-Wformat] Type 2: A class object that does not have a c_str() method is passed in. The accompanying note prompting the user to use the c_str() has no reason be there. Change in Warning diagnostics. (1 instance) C++98: warning: cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs] C++11: warning: format specifies type 'char *' but the argument has type 'HasNoCStr' [-Wformat] Type 3: printf format string is passed in as a pointer instead of a string literal. In both C++98 and C++11, Clang is unable to determine type mismatch at compile type. However, in C++98, non-POD type is not allowed inside variadic arguments. (3 instances) C++98: warning: cannot pass object of non-POD type 'HasCStr' through variadic function; call will abort at runtime [-Wnon-pod-varargs] C++11: (None) test/SemaCXX/warn-thread-safety-parsing.cpp In C++11, does not issue Errors for thread safety attributes applied to static members. http://clang.llvm.org/docs/ThreadSafetyAnalysis.html This may be a side effect of C++11’s relaxation on in-class member initializers. http://www.stroustrup.com/C++11FAQ.html#member-init Restrict the following diagnostics to C++98. (2 instances each) C++98: error: invalid use of non-static data member 'mu' C++98: error: invalid use of member 'mu' in static member function https://reviews.llvm.org/D29685 Files: test/SemaCXX/format-strings.cpp test/SemaCXX/printf-cstr.cpp test/SemaCXX/warn-thread-safety-parsing.cpp
Index: test/SemaCXX/warn-thread-safety-parsing.cpp =================================================================== --- test/SemaCXX/warn-thread-safety-parsing.cpp +++ test/SemaCXX/warn-thread-safety-parsing.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s #define LOCKABLE __attribute__ ((lockable)) #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) @@ -1266,8 +1268,10 @@ void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { } void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu); - static void foo5() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ - // expected-error {{invalid use of member 'mu' in static member function}} + static void foo5() EXCLUSIVE_LOCKS_REQUIRED(mu); +#if __cplusplus <= 199711L + // expected-error@-2 {{invalid use of member 'mu' in static member function}} +#endif template <class T> void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { } @@ -1461,15 +1465,21 @@ mutable Mutex mu; int a GUARDED_BY(mu); - static int si GUARDED_BY(mu); // \ - // expected-error {{invalid use of non-static data member 'mu'}} + static int si GUARDED_BY(mu); +#if __cplusplus <= 199711L + // expected-error@-2 {{invalid use of non-static data member 'mu'}} +#endif - static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ - // expected-error {{invalid use of member 'mu' in static member function}} + static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); +#if __cplusplus <= 199711L + // expected-error@-2 {{invalid use of member 'mu' in static member function}} +#endif friend FooStream& operator<<(FooStream& s, const Foo& f) - EXCLUSIVE_LOCKS_REQUIRED(mu); // \ - // expected-error {{invalid use of non-static data member 'mu'}} + EXCLUSIVE_LOCKS_REQUIRED(mu); +#if __cplusplus <= 199711L + // expected-error@-2 {{invalid use of non-static data member 'mu'}} +#endif }; Index: test/SemaCXX/printf-cstr.cpp =================================================================== --- test/SemaCXX/printf-cstr.cpp +++ test/SemaCXX/printf-cstr.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs +// RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++98 %s -Wno-error=non-pod-varargs +// RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++11 %s -Wno-error=non-pod-varargs #include <stdarg.h> @@ -31,12 +33,39 @@ int n = 10; printf("%d: %s\n", n, hcs.c_str()); - printf("%d: %s\n", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} - printf("%d: %s\n", n, hncs); // expected-warning{{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}} - sprintf(str, "%d: %s", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} - - printf(formatString, hcs, hncs); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} expected-warning{{cannot pass object of non-POD type 'HasNoCStr' through variadic function}} - printf(extstr, hcs, n); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} + printf("%d: %s\n", n, hcs); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} + // expected-note@-3 {{did you mean to call the c_str() method?}} +#else + // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} +#endif + + printf("%d: %s\n", n, hncs); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}} +#else + // expected-warning@-4 {{format specifies type 'char *' but the argument has type 'HasNoCStr'}} +#endif + + sprintf(str, "%d: %s", n, hcs); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} + // expected-note@-3 {{did you mean to call the c_str() method?}} +#else + // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} +#endif + + printf(formatString, hcs, hncs); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}} + // expected-warning@-3 {{cannot pass object of non-POD type 'HasNoCStr' through variadic function}} +#endif + + printf(extstr, hcs, n); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}} +#endif } struct Printf { @@ -49,5 +78,11 @@ const char str[] = "test"; HasCStr hcs(str); Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}} - Printf q("%s %d", hcs, 10); // expected-warning {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} + Printf q("%s %d", hcs, 10); +#if __cplusplus <= 199711L + // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} + // expected-note@-3 {{did you mean to call the c_str() method?}} +#else + // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} +#endif } Index: test/SemaCXX/format-strings.cpp =================================================================== --- test/SemaCXX/format-strings.cpp +++ test/SemaCXX/format-strings.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++11 %s #include <stdarg.h> @@ -9,9 +11,13 @@ } void f(char **sp, float *fp) { - scanf("%as", sp); // expected-warning{{'a' length modifier is not supported by ISO C}} + scanf("%as", sp); +#if __cplusplus <= 199711L + // expected-warning@-2 {{'a' length modifier is not supported by ISO C}} +#else + // expected-warning@-4 {{format specifies type 'float *' but the argument has type 'char **'}} +#endif - // TODO: Warn that the 'a' conversion specifier is a C++11 feature. printf("%a", 1.0); scanf("%afoobar", fp); } @@ -46,11 +52,19 @@ // Test handling __null for format string literal checking. extern "C" { int test_null_format(const char *format, ...) __attribute__((__format__ (__printf__, 1, 2))); +#if __cplusplus >= 201103L + // expected-note@-2 {{candidate function not viable: no known conversion from 'bool' to 'const char *' for 1st argument}} +#endif } void rdar8269537(const char *f) { - test_null_format(false); // expected-warning {{null from a constant boolean}} + test_null_format(false); +#if __cplusplus <= 199711L + // expected-warning@-2 {{null from a constant boolean}} +#else + // expected-error@-4 {{no matching function for call to 'test_null_format'}} +#endif test_null_format(0); // no-warning test_null_format(__null); // no-warning test_null_format(f); // expected-warning {{not a string literal}}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits