This is an archive of the discontinued LLVM Phabricator instance.

Lit C++11 Compatibility - Function Attributes
ClosedPublic

Authored by tigerleapgorge on Feb 7 2017, 2:20 PM.

Details

Summary

I am continuing to make Lit tests C++11 compatible.
This patch contains 3 tests, previously in review 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

Diff Detail

Event Timeline

tigerleapgorge created this revision.Feb 7 2017, 2:20 PM
aaron.ballman edited edge metadata.
aaron.ballman added a subscriber: delesley.

The changes to the format string look good to me, but the changes to the thread-safety attributes do not make sense. I *think* those are indicative of a bug with thready safety analysis, but @delesley would have the definitive answer there. I'm not certain how a static function or variable can be safely guarded by an instance member.

delesley edited edge metadata.Feb 13 2017, 10:19 AM

I agree with Aaron here. Those thread safety errors are supposed to fire; simply disabling the unit tests because they no longer fire is not acceptable. I also don't understand how this could be a bug with the thread safety analysis, since these particular errors are issued when the attributes are parsed, not when the analysis is run. I haven't looked at the relevant code in a long time; have there been significant changes to the attribute-parsing mechanism? There's no member initialization going on here, so why would changes to member initialization have this side effect? I'm confused.

DeLesley

@aaron.ballman Thank you for the code review. I take it I can commit the first 2 tests?

@delesley Thank you for the analysis. Should I open a bugzilla to track this issue?

@aaron.ballman Thank you for the code review. I take it I can commit the first 2 tests?

Yes, the first two tests are good to commit.

tigerleapgorge accepted this revision.Feb 24 2017, 1:06 PM

Of the 3 tests.
format-strings.cpp and printf-cstr.cpp have been commited in r294979
For warn-thread-safety-parsing.cpp, bug 32066 has been filed to track the lack of thread safety errors in C++11

Closing out this code review.

This revision is now accepted and ready to land.Feb 24 2017, 1:06 PM

warn-thread-safety-parsing.cpp has been commited in rL296193.
The following FIXME has been added to track this bug.

//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect