Closed
Description
Projects may use the C preprocessor to achieve polymorphic definitions. For example, consider this macro in safestack.h from OpenSSL:
# define SKM_DEFINE_STACK_OF(t1, t2, t3) \
STACK_OF(t1); \
typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \
typedef void (*sk_##t1##_freefunc)(t3 *a); \
typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \
static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \
{ \
return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \
} \
<... snip ...>
This causes a problem for how we locate ConstraintVariables
. We map PersistentSourceLocations
to ConstraintVariables
inside class ProgramInfo
, but Clang places the spelling location of such definitions inside a scratch space, which can easily lead to namespace collisions. Testing against Icecast on Fedora 29, the following four (completely distinct) functions are associated with <scratch space>:12:1
:
int i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out)
static inline int sk_OPENSSL_CSTRING_unshift(struct stack_st_OPENSSL_CSTRING *sk, const char *ptr) __attribute__((unused))
static inline struct stack_st_void *sk_void_new_null() __attribute__((unused))
void ASN1_IA5STRING_free(ASN1_IA5STRING *a)
Even if the compiler avoided the use of a scratch space for such functions, these collisions would continue to occur in the original file.