Skip to content

Commit 10b43f4

Browse files
authored
[Clang][Sema] Correctly transform dependent operands of overloaded binary operator& (#97596)
Currently, `TreeTransform::TransformCXXOperatorCallExpr` calls `TreeTransform::TransformAddressOfOperand` to transform the first operand of a `CXXOperatorCallExpr` when its `OverloadOperatorKind` is `OO_Amp` -- regardless of arity. This results in the first operand of binary `operator&` being incorrectly transformed as if it was the operand of the address of operator in cases such as the following: ``` struct A { int x; }; void operator&(A, A); template<typename T> struct B { int f() { return T::x & 1; // invalid reference to 'A::x' is not diagnosed because 'T::x' is incorrectly transformed as if it was the operand of unary operator& } }; template struct B<A>; ``` Prior to #92318 we would build a `CXXDependentScopeMemberExpr` for `T::x` (as with most dependent qualified names that were not member qualified names). Since `TreeTransform::TransformAddressOfOperand` only differs from `TransformExpr` for `DependentScopeDeclRefExpr` and `UnresolvedLookupExpr` operands, `T::x` was transformed "correctly". Now that we build a `DependentScopeDeclRefExpr` for `T::x`, it is incorrectly transformed as if it was the operand of the address of operator and we fail to diagnose the invalid reference to a non-static data member. This patch fixes the issue by only calling `TreeTransform::TransformAddressOfOperand` for `CXXOperatorCallExpr`s with a single operand. This fixes #97483.
1 parent 7d68d9d commit 10b43f4

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,8 @@ Bug Fixes to C++ Support
954954
forward-declared class. (#GH93512).
955955
- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
956956
- Fixed an assertion failure about invalid conversion when calling lambda. (#GH96205).
957+
- Fixed a bug where the first operand of binary ``operator&`` would be transformed as if it was the operand
958+
of the address of operator. (#GH97483).
957959

958960
Bug Fixes to AST Handling
959961
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/TreeTransform.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12919,7 +12919,7 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
1291912919
}
1292012920

1292112921
ExprResult First;
12922-
if (E->getOperator() == OO_Amp)
12922+
if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
1292312923
First = getDerived().TransformAddressOfOperand(E->getArg(0));
1292412924
else
1292512925
First = getDerived().TransformExpr(E->getArg(0));
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -verify %s
2+
3+
struct A {
4+
int x;
5+
};
6+
7+
void operator&(A, A);
8+
9+
template<typename T>
10+
struct B {
11+
int f() {
12+
return T::x & 1; // expected-error {{invalid use of non-static data member 'x'}}
13+
}
14+
};
15+
16+
template struct B<A>; // expected-note {{in instantiation of}}

0 commit comments

Comments
 (0)