Skip to content

Commit 1b8830c

Browse files
committed
[clang][Interp] Fix comparing to integral function pointers
We need to account for the fact that the Function pointer is not accessible here. Add FunctionPointer::isWeak() for that.
1 parent 469758c commit 1b8830c

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

clang/lib/AST/Interp/FunctionPointer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ class FunctionPointer final {
3232

3333
const Function *getFunction() const { return Func; }
3434
bool isZero() const { return !Func; }
35+
bool isWeak() const {
36+
if (!Func || !Valid)
37+
return false;
38+
39+
return Func->getDecl()->isWeak();
40+
}
3541

3642
APValue toAPValue() const {
3743
if (!Func)

clang/lib/AST/Interp/Interp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ inline bool CmpHelperEQ<FunctionPointer>(InterpState &S, CodePtr OpPC,
758758

759759
// We cannot compare against weak declarations at compile time.
760760
for (const auto &FP : {LHS, RHS}) {
761-
if (!FP.isZero() && FP.getFunction()->getDecl()->isWeak()) {
761+
if (FP.isWeak()) {
762762
const SourceInfo &Loc = S.Current->getSource(OpPC);
763763
S.FFDiag(Loc, diag::note_constexpr_pointer_weak_comparison)
764764
<< FP.toDiagnosticString(S.getCtx());

clang/test/AST/Interp/c.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -verify=expected,all -std=c11 -Wcast-qual %s
2-
// RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -pedantic -verify=pedantic-expected,all -std=c11 -Wcast-qual %s
2+
// RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -pedantic -verify=pedantic,pedantic-expected,all -std=c11 -Wcast-qual %s
33
// RUN: %clang_cc1 -triple x86_64-linux -verify=ref,all -std=c11 -Wcast-qual %s
4-
// RUN: %clang_cc1 -triple x86_64-linux -pedantic -verify=pedantic-ref,all -std=c11 -Wcast-qual %s
4+
// RUN: %clang_cc1 -triple x86_64-linux -pedantic -verify=pedantic,pedantic-ref,all -std=c11 -Wcast-qual %s
55

66
typedef __INTPTR_TYPE__ intptr_t;
77
typedef __PTRDIFF_TYPE__ ptrdiff_t;
@@ -227,3 +227,9 @@ int castViaInt[*(int*)(unsigned long)"test"]; // ref-error {{variable length arr
227227
// pedantic-ref-error {{variable length array}} \
228228
// expected-error {{variable length array}} \
229229
// pedantic-expected-error {{variable length array}}
230+
231+
const void (*const funcp)(void) = (void*)123; // pedantic-warning {{converts between void pointer and function pointer}}
232+
_Static_assert(funcp == (void*)0, ""); // all-error {{failed due to requirement 'funcp == (void *)0'}} \
233+
// pedantic-warning {{expression is not an integer constant expression}}
234+
_Static_assert(funcp == (void*)123, ""); // pedantic-warning {{equality comparison between function pointer and void pointer}} \
235+
// pedantic-warning {{expression is not an integer constant expression}}

0 commit comments

Comments
 (0)