Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Sema] Allow static_cast<T&&>(e) to check explicit conversions for no…
…n-reference-related types. Summary: [expr.cast.static] states: > 3. A glvalue of type “cv1 T1” can be cast to type “rvalue reference to cv2 T2” if “cv2 T2” is reference-compatible > with “cv1 T1”. The result refers to the object or the specified base class subobject thereof. If T2 is > an inaccessible or ambiguous base class of T1, a program that necessitates such a cast is > ill-formed. > > 4. Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_- > cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t. [...] Currently when checking p3 Clang will diagnose `static_cast<T&&>(e)` as invalid if the argument is not reference compatible with `T`. However I believe the correct behavior is to also check p4 in those cases. For example: ``` double y = 42; static_cast<int&&>(y); // this should be OK. 'int&& t(y)' is well formed ``` Note that we still don't check p4 for non-reference-compatible types which are reference-related since `T&& t(e);` should never be well formed in those cases. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D26231 llvm-svn: 285872
- Loading branch information
Showing
4 changed files
with
70 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
clang/test/CXX/expr/expr.post/expr.static.cast/p3-p4-0x.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s | ||
|
||
|
||
// p3 | ||
// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to | ||
// cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1" (8.5.3). | ||
// p4 | ||
// Otherwise, an expression e can be explicitly converted to a type T using a | ||
// static_cast of the form static_cast<T>(e) if the declaration T t(e); is | ||
// well-formed, for some invented temporary variable t (8.5). [...] | ||
struct A { }; | ||
struct B : A { }; | ||
|
||
struct C { explicit operator A&&(); }; | ||
struct D { operator B(); }; | ||
|
||
template<typename T> T& lvalue(); | ||
template<typename T> T&& xvalue(); | ||
template <typename T> T prvalue(); | ||
|
||
void test(A &a, B &b) { | ||
A &&ar0 = static_cast<A&&>(prvalue<A>()); | ||
A &&ar1 = static_cast<A&&>(prvalue<B>()); | ||
A &&ar2 = static_cast<A&&>(lvalue<C>()); | ||
A &&ar3 = static_cast<A&&>(xvalue<C>()); | ||
A &&ar4 = static_cast<A&&>(prvalue<C>()); | ||
A &&ar5 = static_cast<A&&>(lvalue<D>()); | ||
A &&ar6 = static_cast<A&&>(xvalue<D>()); | ||
A &&ar7 = static_cast<A&&>(prvalue<D>()); | ||
|
||
A &&ar8 = static_cast<A&&>(prvalue<const A>()); // expected-error {{binding value of type 'const A' to reference to type 'A' drops 'const' qualifier}} | ||
A &&ar9 = static_cast<A&&>(lvalue<const A>()); // expected-error {{cannot cast from lvalue of type 'const A'}} | ||
A &&ar10 = static_cast<A&&>(xvalue<const A>()); // expected-error {{cannot cast from rvalue of type 'const A'}} | ||
|
||
const A &&ar11 = static_cast<const A&&>(prvalue<A>()); | ||
const A &&ar12 = static_cast<const A&&>(prvalue<B>()); | ||
const A &&ar13 = static_cast<const A&&>(lvalue<C>()); | ||
const A &&ar14 = static_cast<const A&&>(xvalue<C>()); | ||
const A &&ar15 = static_cast<const A&&>(prvalue<C>()); | ||
const A &&ar16 = static_cast<const A&&>(lvalue<D>()); | ||
|
||
const A &&ar17 = static_cast<const A&&>(prvalue<A const volatile>()); // expected-error {{binding value of type 'const volatile A' to reference to type 'const A' drops 'volatile' qualifier}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters