Skip to content

Address of empty function is not unique #137693

Open
@fekir

Description

@fekir

Consider following snippet (https://godbolt.org/z/beGsh8zoj) compiled at least with -O1:

#include <iostream>

void foo() { __builtin_unreachable(); }
void bar() {}

int main() {
 auto ap = size_t(&foo);
 auto bp = size_t(&bar);

 std::cout 
 << ap << "\n"
 << bp << "\n"
 << ap-bp << "\n"
 << (ap == bp ? "true\n" : "false\n");
}

the output of this programs look like

95027430187360
95027430187360
0
false

clang manages to creates two equal numbers (the difference is 0), that are not equal

I believe this issue is related to #60588 (the oldest one I could find), which was (IMHO wrongly) rejected.

void foo() { __builtin_unreachable(); } does not have undefined behavior as long as it is not called, and taking the address of foo should thus not trigger undefined behavior.

The argument "The problematic code doesn't need to be executed for UB to take effect" is strangely worded.
The function int baz(int i){return 1/i;} also has UB when called as baz(0), but as long as no one calls baz with the parameter 0, there is no UB.

Contrary to most bug reports linked to #60588, the function that would have UB if called, is not called.

As to why one would write something like foo; an example would be to write code for a compiler that does not support __builtin_unreachable; for example

#ifdef PLATFORM_WITH_BUILTIN_UNREACHABLE
void foo() { __builtin_unreachable(); }
#else
void foo() { abort(); }
#endif

// some code that uses foo instead of 
// __builtin_unreachable directly to ensure portability
// with different compilers

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions