You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[clang] Fix side effects resolving overloads of builtin functions (#138651) (#154034)
When parsing `__builtin_addressof(Value)`, where `Value` is a constexpr
variable of primitive type, we will run through
`rewriteBuiltinFunctionDecl`.
`rewriteBuiltinFunctionDecl` is meant to handle a special case which is
not applicable here. (It only applies when a builtin function's type has
a parameter with pointer type, which is not true for
`__builtin_addressof`, not even if the actual argument is a pointer.)
Therefore, `rewriteBuiltinFunctionDecl` returns `nullptr` and things go
on as usual.
But `rewriteBuiltinFunctionDecl` accidentally has a side effect. It
calls `DefaultFunctionArrayLvalueConversion` ->
`DefaultLvalueConversion` -> `CheckLValueToRValueConversionOperand` ->
`rebuildPotentialResultsAsNonOdrUsed` -> `MarkNotOdrUsed`, which removes
the expression from `S.MaybeODRUseExprs`.
This would be correct if `Value` were actually going through an
lvalue-to-rvalue conversion, because it's a constant expression:
https://eel.is/c++draft/basic.def.odr#5.2.2.2
But in this case the conversion is only hypothetical, as part of
`rewriteBuiltinFunctionDecl`'s pseudo-overload-resolution logic.
Fix the side effect by pushing an `ExpressionEvaluationContext`, like we
do for real overload resolution.
Similarly, push a `SFINAETrap` to suppress diagnostics emitted during
`DefaultFunctionArrayLvalueConversion`. This fixes a false-positive
compile error when applying `__builtin_addressof` to certain volatile
union variables, and fixes a duplicated compile error when applying
`__builtin_get_vtable_pointer` to an overloaded function name.
---------
Co-authored-by: Corentin Jabot <[email protected]>
Copy file name to clipboardExpand all lines: clang/test/SemaCXX/builtin-get-vtable-pointer.cpp
-3Lines changed: 0 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -66,9 +66,7 @@ struct PolymorphicTemplate {
66
66
};
67
67
68
68
voidtest_function(int); // expected-note{{possible target for call}}
69
-
// expected-note@-1{{possible target for call}}
70
69
voidtest_function(double); // expected-note{{possible target for call}}
71
-
// expected-note@-1{{possible target for call}}
72
70
73
71
voidgetVTablePointer() {
74
72
ForwardDeclaration *fd = nullptr;
@@ -89,7 +87,6 @@ void getVTablePointer() {
89
87
__builtin_get_vtable_pointer(np_array); // expected-error{{__builtin_get_vtable_pointer requires an argument of polymorphic class pointer type, but 'NonPolymorphic' has no virtual methods}}
90
88
__builtin_get_vtable_pointer(&np_array); // expected-error{{__builtin_get_vtable_pointer requires an argument of class pointer type, but 'NonPolymorphic (*)[1]' was provided}}
91
89
__builtin_get_vtable_pointer(test_function); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
92
-
// expected-error@-1{{reference to overloaded function could not be resolved; did you mean to call it?}}
93
90
Foo<double> Food;
94
91
Foo<int> Fooi;
95
92
__builtin_get_vtable_pointer(Food); // expected-error{{__builtin_get_vtable_pointer requires an argument of class pointer type, but 'Foo<double>' was provided}}
voidunionInSystemHeader1(U1_SystemHeader); // expected-error {{cannot use type 'U1_SystemHeader' for a function/method parameter since it is a union that is non-trivial to destruct}} expected-error {{cannot use type 'U1_SystemHeader' for a function/method parameter since it is a union that is non-trivial to copy}}
90
+
91
+
voidtestAddressof(void) {
92
+
externvolatile U0 t0;
93
+
// These don't dereference so they shouldn't cause an error.
0 commit comments