mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 04:26:07 +00:00

A variable with `weak` attribute signifies that it can be replaced with a "strong" symbol link time. Therefore it must not emitted with "weak_odr" linkage, as that allows the backend to use its value in optimizations. The frontend already considers weak const variables as non-constant (note_constexpr_var_init_weak diagnostic) so this change makes frontend and backend consistent. This commit reverses the f49573d1 weak globals that are const should get weak_odr linkage. commit from 2009-08-05 which introduced this behavior. Unfortunately that commit doesn't provide any details on why the change was made. This was discussed in https://discourse.llvm.org/t/weak-attribute-semantics-on-const-variables/62311 Differential Revision: https://reviews.llvm.org/D126324
32 lines
687 B
C
32 lines
687 B
C
// RUN: %clang_cc1 -w -emit-llvm %s -O1 -o - | FileCheck %s
|
|
// This used to "check for bug compatibility with gcc".
|
|
// Now it checks that that the "weak" declaration makes the value
|
|
// fully interposable whereas a "selectany" one is handled as constant
|
|
// and propagated.
|
|
|
|
// CHECK: @x = weak {{.*}}constant i32 123
|
|
const int x __attribute((weak)) = 123;
|
|
|
|
// CHECK: @y = weak_odr {{.*}}constant i32 234
|
|
const int y __attribute((selectany)) = 234;
|
|
|
|
int* f(void) {
|
|
return &x;
|
|
}
|
|
|
|
int g(void) {
|
|
// CHECK: load i32, ptr @x
|
|
// CHECK-NOT: ret i32 123
|
|
return *f();
|
|
}
|
|
|
|
int *k(void) {
|
|
return &y;
|
|
}
|
|
|
|
int l(void) {
|
|
// CHECK-NOT: load i32, ptr @y
|
|
// CHECK: ret i32 234
|
|
return *k();
|
|
}
|