[clang] 9dbb088 - Perform lvalue conversions on the left of a pseudo-destructor call 'p->~T()'.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 14 22:09:13 PDT 2020
Author: Richard Smith
Date: 2020-10-14T22:09:01-07:00
New Revision: 9dbb0886ea799061baf79d4dce3203524a8468cc
URL: https://github.com/llvm/llvm-project/commit/9dbb0886ea799061baf79d4dce3203524a8468cc
DIFF: https://github.com/llvm/llvm-project/commit/9dbb0886ea799061baf79d4dce3203524a8468cc.diff
LOG: Perform lvalue conversions on the left of a pseudo-destructor call 'p->~T()'.
Previously we failed to convert 'p' from array/function to pointer type,
and to represent the load of 'p' in the AST. The latter causes problems
for constant evaluation.
Added:
Modified:
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/constant-expression-cxx2a.cpp
clang/test/SemaCXX/pseudo-destructors.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d39820fb483d..8d5dccc19726 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7249,8 +7249,8 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
return Base;
}
-static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base,
- tok::TokenKind& OpKind, SourceLocation OpLoc) {
+static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base,
+ tok::TokenKind &OpKind, SourceLocation OpLoc) {
if (Base->hasPlaceholderType()) {
ExprResult result = S.CheckPlaceholderExpr(Base);
if (result.isInvalid()) return true;
@@ -7265,6 +7265,18 @@ static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base,
// Note that this is rather
diff erent from the normal handling for the
// arrow operator.
if (OpKind == tok::arrow) {
+ // The operator requires a prvalue, so perform lvalue conversions.
+ // Only do this if we might plausibly end with a pointer, as otherwise
+ // this was likely to be intended to be a '.'.
+ if (ObjectType->isPointerType() || ObjectType->isArrayType() ||
+ ObjectType->isFunctionType()) {
+ ExprResult BaseResult = S.DefaultFunctionArrayLvalueConversion(Base);
+ if (BaseResult.isInvalid())
+ return true;
+ Base = BaseResult.get();
+ ObjectType = Base->getType();
+ }
+
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
} else if (!Base->isTypeDependent()) {
diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index 2aea2577d972..4adadc9988ab 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -1061,9 +1061,10 @@ namespace memory_leaks {
static_assert(h({new bool(true)})); // ok
}
-void *operator new(std::size_t, void*);
+constexpr void *operator new(std::size_t, void *p) { return p; }
namespace std {
template<typename T> constexpr T *construct(T *p) { return new (p) T; }
+ template<typename T> constexpr void destroy(T *p) { p->~T(); }
}
namespace dtor_call {
@@ -1428,3 +1429,11 @@ namespace PR47805 {
constexpr bool g(B b) { return &b == b.p; }
static_assert(g({}));
}
+
+constexpr bool destroy_at_test() {
+ int n = 0;
+ std::destroy(&n);
+ std::construct(&n);
+ return true;
+}
+static_assert(destroy_at_test());
diff --git a/clang/test/SemaCXX/pseudo-destructors.cpp b/clang/test/SemaCXX/pseudo-destructors.cpp
index 7a5c540794e2..f214f5226ee2 100644
--- a/clang/test/SemaCXX/pseudo-destructors.cpp
+++ b/clang/test/SemaCXX/pseudo-destructors.cpp
@@ -183,3 +183,14 @@ namespace TwoPhaseLookup {
template<typename T> void f6(int *p) { p->TemplateNamesNonTemplate::C::~C<int>(); } // expected-error {{'C' does not refer to a template}}
}
}
+
+void destroy_array_element() {
+ int arr[5];
+ using T = int;
+ arr->~T(); // ok, destroy arr[0].
+}
+
+void destroy_function() {
+ using T = void();
+ destroy_function->~T(); // expected-error {{object expression of non-scalar type 'void ()' cannot be used in a pseudo-destructor expression}}
+}
More information about the cfe-commits
mailing list