Skip to content

Commit

Permalink
Revert "Reapply "[Clang][Sema] Earlier type checking for builtin unar…
Browse files Browse the repository at this point in the history
…y operators (llvm#90500)" (llvm#92283)"

This reverts commit 1595988.

rdar://131028403

Conflicts:
	clang/docs/ReleaseNotes.rst
  • Loading branch information
ahatanaka committed Jul 18, 2024
1 parent 1fbdf73 commit 3d14a60
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 598 deletions.
15 changes: 0 additions & 15 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,6 @@ C++ Specific Potentially Breaking Changes

- Clang now rejects pointer to member from parenthesized expression in unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906).

- Clang now performs semantic analysis for unary operators with dependent operands
that are known to be of non-class non-enumeration type prior to instantiation.

This change uncovered a bug in libstdc++ 14.1.0 which may cause compile failures
on systems using that version of libstdc++ and Clang 19, with an error that looks
something like this:

.. code-block:: text
<source>:4:5: error: expression is not assignable
4 | ++this;
| ^ ~~~~
To fix this, update libstdc++ to version 14.1.1 or greater.

ABI Changes in This Version
---------------------------
- Fixed Microsoft name mangling of implicitly defined variables used for thread
Expand Down
5 changes: 1 addition & 4 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -8079,10 +8079,7 @@ inline bool Type::isUndeducedType() const {
/// Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
if (!CanonicalType->isDependentType())
return isRecordType() || isEnumeralType();
return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
!isMemberPointerType();
return isDependentType() || isRecordType() || isEnumeralType();
}

/// Determines whether this type is written as a typedef-name.
Expand Down
363 changes: 186 additions & 177 deletions clang/lib/Sema/SemaExpr.cpp

Large diffs are not rendered by default.

17 changes: 10 additions & 7 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -16313,11 +16313,10 @@ ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
}
} else {
if (!First->isTypeDependent() && !Second->isTypeDependent() &&
!First->getType()->isOverloadableType() &&
if (!First->getType()->isOverloadableType() &&
!Second->getType()->isOverloadableType()) {
// Neither of the arguments is type-dependent or has an overloadable
// type, so try to create a built-in binary operation.
// Neither of the arguments is an overloadable type, so try to
// create a built-in binary operation.
BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
ExprResult Result
= SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
Expand All @@ -16328,8 +16327,12 @@ ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
}
}

// Add any functions found via argument-dependent lookup.
Expr *Args[2] = { First, Second };
unsigned NumArgs = 1 + (Second != nullptr);

// Create the overloaded operator invocation for unary operators.
if (!Second || isPostIncDec) {
if (NumArgs == 1 || isPostIncDec) {
UnaryOperatorKind Opc
= UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
Expand All @@ -16338,8 +16341,8 @@ ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(

// Create the overloaded operator invocation for binary operators.
BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
First, Second, RequiresADL);
ExprResult Result = SemaRef.CreateOverloadedBinOp(
OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL);
if (Result.isInvalid())
return ExprError();

Expand Down
4 changes: 2 additions & 2 deletions clang/test/AST/ast-dump-expr-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4261,9 +4261,9 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "V"
// CHECK-NEXT: "qualType": "<dependent type>"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "isPostfix": false,
// CHECK-NEXT: "opcode": "*",
// CHECK-NEXT: "canOverflow": false,
Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/ast-dump-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'V'
// CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:8> 'NULL TYPE'
// CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:8> 'V' lvalue prefix '*' cannot overflow
// CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:8> '<dependent type>' prefix '*' cannot overflow
// CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this
}
};
Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/ast-dump-lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | | | `-CompoundStmt {{.*}} <col:15, col:16>
// CHECK-NEXT: | | `-FieldDecl {{.*}} <col:8> col:8{{( imported)?}} implicit 'V'
// CHECK-NEXT: | |-ParenListExpr {{.*}} <col:8> 'NULL TYPE'
// CHECK-NEXT: | | `-UnaryOperator {{.*}} <col:8> 'V' lvalue prefix '*' cannot overflow
// CHECK-NEXT: | | `-UnaryOperator {{.*}} <col:8> '<dependent type>' prefix '*' cannot overflow
// CHECK-NEXT: | | `-CXXThisExpr {{.*}} <col:8> 'V *' this
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:15, col:16>
// CHECK-NEXT: |-DeclStmt {{.*}} <line:22:3, col:11>
Expand Down
65 changes: 0 additions & 65 deletions clang/test/CXX/expr/expr.unary/expr.unary.general/p1.cpp

This file was deleted.

158 changes: 30 additions & 128 deletions clang/test/CXX/over/over.built/ast.cpp
Original file line number Diff line number Diff line change
@@ -1,139 +1,41 @@
// RUN: %clang_cc1 -std=c++17 -Wno-unused -ast-dump %s -ast-dump-filter Test | FileCheck %s
// RUN: %clang_cc1 -std=c++17 -ast-dump %s -ast-dump-filter Test | FileCheck %s

namespace Test {
template<typename T, typename U>
void Unary(T t, T* pt, T U::* mpt, T(&ft)(), T(&at)[4]) {
// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '*' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
*t;
struct A{};

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '+' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
+t;
template <typename T, typename U>
auto Test(T* pt, U* pu) {
// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '*'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
(void)*pt;

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '-' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
-t;
// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '++'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
(void)(++pt);

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '!' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
!t;
// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '+'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
(void)(+pt);

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '~' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
~t;
// CHECK: BinaryOperator {{.*}} '<dependent type>' '+'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
(void)(pt + 3);

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '&' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
&t;
// CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
(void)(pt - pt);

// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '++' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
++t;
// CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
(void)(pt - pu);

// CHECK: UnaryOperator {{.*}} '<dependent type>' lvalue prefix '--' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T' lvalue ParmVar {{.*}} 't' 'T'
--t;
// CHECK: BinaryOperator {{.*}} '<dependent type>' '=='
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
(void)(pt == pu);

// CHECK: UnaryOperator {{.*}} 'T' lvalue prefix '*' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
*pt;
}

// CHECK: UnaryOperator {{.*}} 'T *' prefix '+' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
+pt;

// CHECK: UnaryOperator {{.*}} 'bool' prefix '!' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool' <PointerToBoolean>
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
!pt;

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '&' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
&pt;

// CHECK: UnaryOperator {{.*}} 'T *' lvalue prefix '++' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
++pt;

// CHECK: UnaryOperator {{.*}} 'T *' lvalue prefix '--' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
--pt;

// CHECK: UnaryOperator {{.*}} 'bool' prefix '!' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool' <MemberPointerToBoolean>
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T U::*' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T U::*' lvalue ParmVar {{.*}} 'mpt' 'T U::*'
!mpt;

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '&' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T U::*' lvalue ParmVar {{.*}} 'mpt' 'T U::*'
&mpt;

// CHECK: UnaryOperator {{.*}} 'T ()' lvalue prefix '*' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T (*)()' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T ()' lvalue ParmVar {{.*}} 'ft' 'T (&)()'
*ft;

// CHECK: UnaryOperator {{.*}} 'T (*)()' prefix '+' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T (*)()' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T ()' lvalue ParmVar {{.*}} 'ft' 'T (&)()'
+ft;

// CHECK: UnaryOperator {{.*}} 'bool' prefix '!' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool' <PointerToBoolean>
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T (*)()' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T ()' lvalue ParmVar {{.*}} 'ft' 'T (&)()'
!ft;

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '&' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T ()' lvalue ParmVar {{.*}} 'ft' 'T (&)()'
&ft;

// CHECK: UnaryOperator {{.*}} 'T' lvalue prefix '*' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <ArrayToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T[4]' lvalue ParmVar {{.*}} 'at' 'T (&)[4]'
*at;

// CHECK: UnaryOperator {{.*}} 'T *' prefix '+' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <ArrayToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T[4]' lvalue ParmVar {{.*}} 'at' 'T (&)[4]'
+at;

// CHECK: UnaryOperator {{.*}} 'bool' prefix '!' cannot overflow
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool' <PointerToBoolean>
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'T *' <ArrayToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'T[4]' lvalue ParmVar {{.*}} 'at' 'T (&)[4]'
!at;

// CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '&' cannot overflow
// CHECK-NEXT: DeclRefExpr {{.*}} 'T[4]' lvalue ParmVar {{.*}} 'at' 'T (&)[4]'
&at;
}

template<typename T, typename U>
void Binary(T* pt, U* pu) {
// CHECK: BinaryOperator {{.*}} '<dependent type>' '+'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
pt + 3;

// CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
pt - pt;

// CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
pt - pu;

// CHECK: BinaryOperator {{.*}} '<dependent type>' '=='
// CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
// CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
pt == pu;
}
} // namespace Test
2 changes: 1 addition & 1 deletion clang/test/CXX/over/over.built/p10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ void f(int i, float f, bool b, char c, int* pi, A* pa, T* pt) {

(void)-pi; // expected-error {{invalid argument type}}
(void)-pa; // expected-error {{invalid argument type}}
(void)-pt; // expected-error {{invalid argument type}}
(void)-pt; // FIXME: we should be able to give an error here.
}

2 changes: 1 addition & 1 deletion clang/test/CXX/over/over.built/p11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ void f(int i, float f, bool b, char c, int* pi, T* pt) {
(void)~b;
(void)~c;
(void)~pi; // expected-error {{invalid argument type}}
(void)~pt; // expected-error {{invalid argument type}}
(void)~pt; // FIXME: we should be able to give an error here.
}

Loading

0 comments on commit 3d14a60

Please sign in to comment.