[PATCH] D21626: Lit C++11 Compatibility Patch #10
Charles Li via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 22 15:41:32 PDT 2016
tigerleapgorge created this revision.
tigerleapgorge added a reviewer: rsmith.
tigerleapgorge added a subscriber: cfe-commits.
Hi Everyone,
I am continuing with updating the Lit tests for C++11 compatibility.
11 tests this time.
test/Modules/Inputs/merge-using-decls/a.h
test/Modules/Inputs/merge-using-decls/b.h
test/Modules/merge-using-decls.cpp
This test verifies the interaction between Modules and Using declarations.
Part of this test, template struct “E” checks for mismatch between using declarations in a.h and Access declarations in b.h.
Since C++11 has deprecated Access declarations, module “B” will fail to build.
Therefore, I have restricted this part of the test to only use C++98.
test/OpenMP/declare_reduction_messages.cpp
In C++11, an opening square bracket is the start of a lambda capture.
Therefore, a unmatched opening square bracket will cause the following diagnostics change.
C++98: error: expected '(' after 'initializer'
error: expected expression
warning: extra tokens at the end of '#pragma omp declare reduction' are ignored [-Wextra-tokens]
C++11: error: expected '(' after 'initializer'
error: expected variable name or 'this' in lambda capture list
error: expected ')'
note: to match this '('
test/OpenMP/openmp_check.cpp
This test is created in response to bug 25221, where C++11 code running under C++98 causes the parser to go into an infinite loop.
Since this is C++11 code, all expected diagnostics will go away when compiling at C++11.
Therefore, guard all of the following diagnostics under C++98.
C++98: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
error: expected expression
error: expected ';' at end of declaration
C++98: error: C++ requires a type specifier for all declarations
C++98: error: expected unqualified-id
C++98: error: extraneous closing brace ('}')
test/SemaCXX/MicrosoftExtensions.cpp
This test checks for Microsoft extensions.
Portions of this test check for unsupported C++11 features when compiling at C++98.
Guard all such diagnostics under C++98.
Base destructor being marked with “throw()”, derived destructor is not.
This no longer results in the following diagnostics in C++11.
C++98: warning: exception specification of overriding function is more lax than base version [-Wmicrosoft-exception-spec]
note: overridden virtual function is here
Enum with underlying type is now supported in C++11. Guard the following under C++98.
C++98: warning: enumeration types with a fixed underlying type are a C++11 extension [-Wc++11-extensions]
C++98: warning: enumeration types with a fixed underlying type are a C++11 extension [-Wc++11-extensions]
“override” is now supported in C++11. Guard the following under C++98.
C++98: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
test/SemaCXX/PR9572.cpp
This test verifies 2 types of diagnostics.
Type 1:
Warning for unsupported C++11 feature when compiling at C++98.
Guard the following Warning under C++98.
C++98: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
Type 2:
Errors when derived class inherit a private virtual destructor in the base class.
Class Base has a private virtual destructor.
Struct Foo inherits Base. Foo does not explicitly declare a destructor.
Struct Bar inherits Foo. Bar explicitly declares a destructor.
Struct Baz contains an instance of Foo as its member.
Because C++11 introduced ‘delete’, this results in the following changes in diagnostics.
C++98 issues 1 Error on Base’s private destructor.
C++11 issues 4 Errors at all points of the inheritance chain where the destructor is implicitly deleted.
C++98: error: base class 'Base' has private destructor
note: implicitly declared private here
note: implicit destructor for 'Foo' first required here
C++11: error: deleted function '~Foo' cannot override a non-deleted function
note: overridden virtual function is here
C++11: error: non-deleted function '~Bar' cannot override a deleted function
note: overridden virtual function is here
C++11: error: attempt to use a deleted function
note: destructor of 'Foo' is implicitly deleted because base class 'Base' has an inaccessible destructor
C++11: error: attempt to use a deleted function
note: destructor of 'Foo' is implicitly deleted because base class 'Base' has an inaccessible destructor
test/SemaCXX/default-assignment-operator.cpp
C++11 introduced ‘delete’.
Change in diagnostics regarding implicitly deleted copy assignment operator.
This test change contains 3 parts: Test1, Test5, ProtectedCheck.
Test1
Class Base has a member “int &ref” that is never initialized.
Class X is derived from Base.
Neither Base nor X explicitly declare their copy assignment operator.
In C++98, Clang issues one error for each implicit class copy assignment operator definition failure (“Base” and “X”).
In C++11, Clang issues one error for each assignment statement of the class instance. (“x = cx;” and “x = cx;”)
And since there are 2 copy assignments of x, there are 2 sets of identical diagnostics in C++11.
C++98: error: cannot define the implicit copy assignment operator for 'Base', because non-static reference member 'ref' cannot use copy assignment operator
note: declared here
note: implicit copy assignment operator for 'Base' first required here
error: cannot define the implicit copy assignment operator for 'X', because non-static const member 'cint' cannot use copy assignment operator
note: declared here
note: implicit copy assignment operator for 'X' first required here
C++11: error: object of type 'X' cannot be assigned because its copy assignment operator is implicitly deleted
note: copy assignment operator of 'X' is implicitly deleted because base class 'Base' has a deleted copy assignment operator
note: copy assignment operator of 'Base' is implicitly deleted because field 'ref' is of reference type 'int &'
error: object of type 'X' cannot be assigned because its copy assignment operator is implicitly deleted
note: copy assignment operator of 'X' is implicitly deleted because base class 'Base' has a deleted copy assignment operator
note: copy assignment operator of 'Base' is implicitly deleted because field 'ref' is of reference type 'int &'
Test5
Class E1 has a constant integer member ‘a’. E1 has a default constructor “E1() : a(0) {}”.
Two instances of E1 are created, e1 and e2. e2 is assigned to e1.
Change in diagnostics messages.
C++98: error: cannot define the implicit copy assignment operator for 'E1', because non-static const member 'a' cannot use copy assignment operator
note: declared here
note: implicit copy assignment operator for 'E1' first required here
C++11: error: object of type 'E1' cannot be assigned because its copy assignment operator is implicitly deleted
note: copy assignment operator of 'E1' is implicitly deleted because field 'a' is of const-qualified type 'const int'
ProtectedCheck
Class X has a protected copy assignment operator.
Struct Z contains an instance of X.
An instance of Z, z, is copy assigned to itself (z = z).
C++98 and C++11 issues different diagnostics.
C++98: error: 'operator=' is a protected member of 'ProtectedCheck::X'
note: declared protected here
note: implicit copy assignment operator for 'ProtectedCheck::Z' first required here
C++11: error: object of type 'ProtectedCheck::Z' cannot be assigned because its copy assignment operator is implicitly deleted
note: copy assignment operator of 'Z' is implicitly deleted because field 'x' has an inaccessible copy assignment operator
test/SemaCXX/default-constructor-initializers.cpp
C++11 introduced ‘delete’.
As a result, implicitly deleted default constructor diagnostics changed.
http://en.cppreference.com/w/cpp/language/default_constructor
Part 1
X1 has no implicitly default constructor.
X2 inherits X1.
X3 inherits X2.
X3 is instantiated.
C++98: error: implicit default constructor for 'X3' must explicitly initialize the base class 'X2' which does not have a default constructor
note: 'X2' declared here
note: implicit default constructor for 'X3' first required here
C++11: error: call to implicitly-deleted default constructor of 'X3'
note: default constructor of 'X3' is implicitly deleted because base class 'X2' has no default constructor
Part 2.
X4 contains an instance of X2 and a reference of X2.
C++98 issues 2 Errors, one for each member of the class.
C++11 issues 1 Error, for the instantiation of the class.
C++98: error: implicit default constructor for 'X4' must explicitly initialize the member 'x2' which does not have a default constructor
note: member is declared here
note: 'X2' declared here
C++98: error: implicit default constructor for 'X4' must explicitly initialize the reference member 'rx2'
note: declared here
note: implicit default constructor for 'X4' first required here
C++11: error: call to implicitly-deleted default constructor of 'X4'
note: default constructor of 'X4' is implicitly deleted because field 'x2' has no default constructor
Part 3.
Z1 has 3 members: integer reference z, constant integer c1 and volatile integer v1.
None of which are explicitly initialized.
Therefore, Z1 has no implicitly default constructor.
C++98 issues 2 Errors. One for the integer reference member. One for the constant integer member.
C++11 issues 1 Error for the instantiation of the class.
C++98: error: implicit default constructor for 'Z1' must explicitly initialize the reference member 'z'
note: declared here
error: implicit default constructor for 'Z1' must explicitly initialize the const member 'c1'
note: declared here
note: implicit default constructor for 'Z1' first required here
C++11: error: call to implicitly-deleted default constructor of 'Z1'
note: default constructor of 'Z1' is implicitly deleted because field 'z' of reference type 'int &' would not be initialized
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 change contains 4 parts.
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.
Part 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]
Part 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]
Part 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.(2 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)
Part 4
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. (1 instance)
C++98: warning: cannot pass object of non-POD type 'HasNoCStr' through variadic function; call will abort at runtime [-Wnon-pod-varargs]
C++11: (None)
test/SemaCXX/virtual-base-used.cpp
The base class explicitly declares a public virtual destructor.
The derived class does not explicitly declare a destructor.
The derived class contains a member with an inaccessible private destructor.
In C++98, Clang Warns about the private destructor then gives a Note at class instantiation (MSABI) or class method definition.
In C++11, The derived class having a member that can not be destroyed means the derived class’s own implicit destructor is deleted.
Therefore, Clang issues an Error on the derived class’s deleted destructor trying to overwrite base class’s non-deleted destructor.
Furthermore, Clang also issues Errors on classes further down the inheritance chain with explicitly declared destructors trying to
overwrite first derived class’s implicitly deleted destructor.
This test is subdivide into three sections. Each section has its own inheritance chain.
Section 1:
A is the base struct with a virtual destructor.
B derives from A. B has a member class instance ‘x’ with an inaccessible destructor.
D derives from B. D has an explicitly declared destructor.
In C++98, Clang issues an Error about B’s x having no accessible destructor.
In C++11, Clang issues 2 Errors.
First Error on B’s implicitly deleted destructor inheriting A’s explicitly declared destructor.
Second Error on D’s explicitly declared destructor inheriting B’s implicitly deleted destructor.
C++98: error: field of type 'NoDestroy' has private destructor
note: implicitly declared private here
note: implicit destructor for 'B' first required here
C++11: error: deleted function '~B' cannot override a non-deleted function
note: overridden virtual function is here
error: non-deleted function '~D' cannot override a deleted function
note: overridden virtual function is here
Section 2:
A is the base struct with a virtual destructor.
E derives A. E also has a member class instance x with no destructor.
F derives from E and has no explicitly declared destructor.
G derives from F and has an explicitly declared destructor.
In C++98, Clang issues an Error about E’s x having no accessible destructor.
In C++11, Clang issues 3 Errors.
First Error about E’s implicitly deleted destructor inheriting A’s explicitly declared destructor.
Second Error about F’s implicitly declared destructor inheriting E’s implicitly deleted destructor.
Third Error about G’s explicitly declared destructor inheriting F’s now implicitly deleted destructor.
C++98: error: field of type 'NoDestroy' has private destructor
note: implicitly declared private here
note: implicit destructor for 'E' first required here
C++11: error: deleted function '~E' cannot override a non-deleted function
note: overridden virtual function is here
error: non-deleted function '~F' cannot override a deleted function
note: overridden virtual function is here
error: non-deleted function '~G' cannot override a deleted function
note: overridden virtual function is here
Section 3:
A is a struct with a virtual destructor.
H derives from A. H has a member x with an inaccessible destructor.
I derives from H.
J derives from I. J has a member function foo() definition.
In C++98, Clang issues an error on the H’s member X having an private destructor.
In C++11, Clang issues 2 errors.
First Error on H’s implicitly deleted destructor inheriting A’s explicitly declared destructor.
Second Error on I’s explicitly declared destructor inheriting H’s implicitly deleted destructor.
C++98: error: field of type 'NoDestroy' has private destructor
note: implicitly declared private here
note: implicit destructor for 'H' first required here
C++11: error: deleted function '~H' cannot override a non-deleted function
note: overridden virtual function is here
error: non-deleted function '~I' cannot override a deleted function
note: overridden virtual function is here
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
Cheers,
Charles Li
http://reviews.llvm.org/D21626
Files:
test/Modules/Inputs/merge-using-decls/a.h
test/Modules/Inputs/merge-using-decls/b.h
test/Modules/merge-using-decls.cpp
test/OpenMP/declare_reduction_messages.cpp
test/OpenMP/openmp_check.cpp
test/SemaCXX/MicrosoftExtensions.cpp
test/SemaCXX/PR9572.cpp
test/SemaCXX/default-assignment-operator.cpp
test/SemaCXX/default-constructor-initializers.cpp
test/SemaCXX/format-strings.cpp
test/SemaCXX/printf-cstr.cpp
test/SemaCXX/virtual-base-used.cpp
test/SemaCXX/warn-thread-safety-parsing.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21626.61620.patch
Type: text/x-patch
Size: 38863 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160622/72303b3e/attachment-0001.bin>
More information about the cfe-commits
mailing list