llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.06k stars 11.98k forks source link

Dependence on anonymity should grant private linkage #6164

Open rjmccall opened 14 years ago

rjmccall commented 14 years ago
Bugzilla Link 5792
Version trunk
OS All
Blocks llvm/llvm-project#5593
CC @DougGregor,@zygoloid

Extended Description

The current implementation of anonymous namespaces gives private linkage to all entities semantically contained in an anonymous namespace. This is conservative; I claim we can extend this to all "anonymous" objects, where an object is anonymous iff:

1) It is declared within an anonymous namespace. 2) It is declared static. 3) It is a class or function template specialization with an anonymous template argument. 4) it is a function with an anonymous argument type.

The rules of C++ forbid such objects from being referenced outside the current translation unit.

In fact, having them be non-private could theoretically cause spurious link errors.

rjmccall commented 9 years ago

Note that Chris's example only applies to inline definitions, where the ODR constrains both the tokens and the identity of the declarations referenced within the definition. Also note that non-ODR uses of const non-volatile internal objects of literal type with constant initializers are a (quite) specific exception to the rule.

I'd be kindof concerned about actually applying that rule, since nobody else does it, and since it's quite easy to make a spurious ODR use (canonical example: passing an argument to a forwarding function template that takes a const T& / T&&). But we might be able to be carefully broaden the exception enough to stay out of trouble.

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 9 years ago

We handle all the items in comment#0, but not the case in comment#1.

DougGregor commented 14 years ago

This is mostly implemented here:

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100201/027083.html

See the laundry list at the end of the commit message for the bits that aren't done.

lattner commented 14 years ago

It goes beyond that, if an anonymous decl is referenced in any inline function definition, it should also be anonymous:

namespace { int x; }

inline int foo() { return x; }

int bar() { return foo(); }

'foo' can't be referenced outside the translation unit due to ODR. llvm-gcc gives it linkonce linkage, but giving it internal linkage would be better.