aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorChris Bieneman <chris.bieneman@me.com>2019-05-17 05:45:57 +0000
committerChris Bieneman <chris.bieneman@me.com>2019-05-17 05:45:57 +0000
commita5a4124c494ce08a9decb96d2be94e7f216bedbd (patch)
tree7405e4aeac6dcd87e0e49e3ed17080a907235bee /clang
parente18a6ad0b8b7d670bb06ec3ed5eb348cec9e6133 (diff)
downloadllvm-a5a4124c494ce08a9decb96d2be94e7f216bedbd.zip
llvm-a5a4124c494ce08a9decb96d2be94e7f216bedbd.tar.gz
llvm-a5a4124c494ce08a9decb96d2be94e7f216bedbd.tar.bz2
Revert [c++20] P1327R1: Support for typeid applied to objects of polymorphic class type in constant evaluation.
This reverts r360977 (git commit f51dc8d2f98f4029247552bc45ef53628ab3b6b9) llvm-svn: 360987
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticASTKinds.td28
-rw-r--r--clang/lib/AST/ExprConstant.cpp28
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx2a.cpp59
-rwxr-xr-xclang/www/cxx_status.html3
4 files changed, 20 insertions, 98 deletions
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index a9e88d5..3e9ebbb 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -12,8 +12,7 @@ let Component = "AST" in {
def note_expr_divide_by_zero : Note<"division by zero">;
def note_constexpr_invalid_cast : Note<
"%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
- " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression"
- "%select{| in C++ standards before C++2a||}0">;
+ " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression">;
def note_constexpr_invalid_downcast : Note<
"cannot cast object of dynamic type %0 to type %1">;
def note_constexpr_overflow : Note<
@@ -32,13 +31,12 @@ def note_constexpr_invalid_inhctor : Note<
def note_constexpr_no_return : Note<
"control reached end of constexpr function">;
def note_constexpr_virtual_call : Note<
- "cannot evaluate call to virtual function in a constant expression "
- "in C++ standards before C++2a">;
+ "cannot evaluate call to virtual function in a constant expression">;
def note_constexpr_pure_virtual_call : Note<
"pure virtual function %q0 called">;
def note_constexpr_polymorphic_unknown_dynamic_type : Note<
- "%select{||||virtual function called on|dynamic_cast applied to|"
- "typeid applied to}0 object '%1' whose dynamic type is not constant">;
+ "%select{||||virtual function called on|dynamic_cast applied to}0 "
+ "object '%1' whose dynamic type is not constant">;
def note_constexpr_dynamic_cast_to_reference_failed : Note<
"reference dynamic_cast failed: %select{"
"static type %1 of operand is a non-public base class of dynamic type %2|"
@@ -92,7 +90,7 @@ def note_constexpr_var_init_non_constant : Note<
"initializer of %0 is not a constant expression">;
def note_constexpr_typeid_polymorphic : Note<
"typeid applied to expression of polymorphic type %0 is "
- "not allowed in a constant expression in C++ standards before C++2a">;
+ "not allowed in a constant expression">;
def note_constexpr_void_comparison : Note<
"comparison between unequal pointers to void has unspecified result">;
def note_constexpr_temporary_here : Note<"temporary created here">;
@@ -110,11 +108,11 @@ def note_constexpr_this : Note<
"evaluation of a call to a 'constexpr' member function">;
def note_constexpr_lifetime_ended : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"%select{temporary|variable}1 whose lifetime has ended">;
def note_constexpr_access_uninit : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"object outside its lifetime is not allowed in a constant expression">;
def note_constexpr_use_uninit_reference : Note<
"use of reference outside its lifetime "
@@ -141,30 +139,30 @@ def note_constexpr_ltor_incomplete_type : Note<
"read of incomplete type %0 is not allowed in a constant expression">;
def note_constexpr_access_null : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"dereferenced null pointer is not allowed in a constant expression">;
def note_constexpr_access_past_end : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"dereferenced one-past-the-end pointer is not allowed in a constant expression">;
def note_constexpr_access_unsized_array : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"element of array without known bound "
"is not allowed in a constant expression">;
def note_constexpr_access_inactive_union_member : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "dynamic_cast of}0 "
"member %1 of union with %select{active member %3|no active member}2 "
"is not allowed in a constant expression">;
def note_constexpr_access_static_temporary : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 temporary "
+ "dynamic_cast of}0 temporary "
"is not allowed in a constant expression outside the expression that "
"created the temporary">;
def note_constexpr_access_unreadable_object : Note<
"%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 object '%1' whose value is not known">;
+ "dynamic_cast of}0 object '%1' whose value is not known">;
def note_constexpr_modify_global : Note<
"a constant expression cannot modify an object that is visible outside "
"that expression">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 35000f4..e41264e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1349,7 +1349,6 @@ enum AccessKinds {
AK_Decrement,
AK_MemberCall,
AK_DynamicCast,
- AK_TypeId,
};
static bool isModification(AccessKinds AK) {
@@ -1357,7 +1356,6 @@ static bool isModification(AccessKinds AK) {
case AK_Read:
case AK_MemberCall:
case AK_DynamicCast:
- case AK_TypeId:
return false;
case AK_Assign:
case AK_Increment:
@@ -6031,33 +6029,19 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
}
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
- TypeInfoLValue TypeInfo;
-
if (!E->isPotentiallyEvaluated()) {
+ TypeInfoLValue TypeInfo;
if (E->isTypeOperand())
TypeInfo = TypeInfoLValue(E->getTypeOperand(Info.Ctx).getTypePtr());
else
TypeInfo = TypeInfoLValue(E->getExprOperand()->getType().getTypePtr());
- } else {
- if (!Info.Ctx.getLangOpts().CPlusPlus2a) {
- Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
- << E->getExprOperand()->getType()
- << E->getExprOperand()->getSourceRange();
- }
-
- if (!Visit(E->getExprOperand()))
- return false;
-
- Optional<DynamicType> DynType =
- ComputeDynamicType(Info, E, Result, AK_TypeId);
- if (!DynType)
- return false;
-
- TypeInfo =
- TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
+ return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
}
- return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
+ Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
+ << E->getExprOperand()->getType()
+ << E->getExprOperand()->getSourceRange();
+ return false;
}
bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index 90980c8d..c49d670 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -2,10 +2,6 @@
#include "Inputs/std-compare.h"
-namespace std {
- struct type_info;
-};
-
namespace ThreeWayComparison {
struct A {
int n;
@@ -358,58 +354,3 @@ namespace DynamicCast {
// expected-note@+1 {{reference dynamic_cast failed: dynamic type 'DynamicCast::G' of operand does not have a base class of type 'DynamicCast::Unrelated'}}
constexpr int e_unrelated = (dynamic_cast<Unrelated&>((E&)g), 0); // expected-error {{}}
}
-
-namespace TypeId {
- struct A {
- const std::type_info &ti = typeid(*this);
- };
- struct A2 : A {};
- static_assert(&A().ti == &typeid(A));
- static_assert(&typeid((A2())) == &typeid(A2));
- extern A2 extern_a2;
- static_assert(&typeid(extern_a2) == &typeid(A2));
-
- constexpr A2 a2;
- constexpr const A &a1 = a2;
- static_assert(&typeid(a1) == &typeid(A));
-
- struct B {
- virtual void f();
- const std::type_info &ti1 = typeid(*this);
- };
- struct B2 : B {
- const std::type_info &ti2 = typeid(*this);
- };
- static_assert(&B2().ti1 == &typeid(B));
- static_assert(&B2().ti2 == &typeid(B2));
- extern B2 extern_b2;
- // expected-note@+1 {{typeid applied to object 'extern_b2' whose dynamic type is not constant}}
- static_assert(&typeid(extern_b2) == &typeid(B2)); // expected-error {{constant expression}}
-
- constexpr B2 b2;
- constexpr const B &b1 = b2;
- static_assert(&typeid(b1) == &typeid(B2));
-
- constexpr bool side_effects() {
- // Not polymorphic nor a glvalue.
- bool OK = true;
- (void)typeid(OK = false, A2()); // expected-warning {{has no effect}}
- if (!OK) return false;
-
- // Not polymorphic.
- A2 a2;
- (void)typeid(OK = false, a2); // expected-warning {{has no effect}}
- if (!OK) return false;
-
- // Not a glvalue.
- (void)typeid(OK = false, B2()); // expected-warning {{has no effect}}
- if (!OK) return false;
-
- // Polymorphic glvalue: operand evaluated.
- OK = false;
- B2 b2;
- (void)typeid(OK = true, b2); // expected-warning {{will be evaluated}}
- return OK;
- }
- static_assert(side_effects());
-}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 5acdd56..84552c2 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -973,11 +973,10 @@ as the draft C++2a standard evolves.
</tr>
<tr>
<td><a href="http://wg21.link/p1327r1">P1327R1</a></td>
- <td class="svn" align="center">SVN</td>
+ <td rowspan=2 class="none" align="center">No</td>
</tr>
<tr>
<td><a href="http://wg21.link/p1330r0">P1330R0</a></td>
- <td class="none" align="center">No</td>
</tr>
<tr>
<td>Prohibit aggregates with user-declared constructors</td>