Brief
There is a bug pertaining to Builtin functions with address-space-qualified pointer operands.
Context
clang::Sema::ActOnCallExpr visits every call expression to perform type checking and symbol table lookup. In doing so, it may call rewriteBuiltinFunctionDecl in order to specialize a non-address-space-qualified builtin function against the address-space qualifiers of a callsite's actual parameters.
Function rewriteBuiltinFunctionDecl compares the type of each formal parameter to the type of the corresponding actual parameter, in turn. If it detects a mismatch in the address spaces of pointer operands, it sets NeedsNewDecl=true and specializes the declaration accordingly.
Bug
The test for operand type mismatch is incorrect; specifically, it tests the address-space qualifiers of the pointer, rather than the pointee type. Instead of testing "ParamType.getQualifiers().hasAddressSpace() it should test "ParamType->getPointeeType().getQualifiers().hasAddressSpace()"
Pointer to (Address-Space-Qualified T) vs (Address-Space-Qualified Pointer) to T
Suppose that my target's builtin file (include/clang/Basic/BuiltinsXXX.def) declares this builtin with an address-space-qualfied pointer operand:
// v4i32 __builtin_FOO(volatile addrspace(109) v4i32 *a, v4i32 b) BUILTIN(__builtin_FOO, "V4iV4iD*109V4i", "n")
In the pre-patch system, I can observe the parameter type by placing a breakpoint on the line that sets NeedsNewDecl=true, and then dumping the parameter type:
$ cat testcase.cpp typedef int __attribute__((vector_size(4*sizeof(int)))) v4i32; void test() { v4i32 volatile __attribute__((address_space(109))) *A; v4i32 B; __builtin_FOO( A, B ); } $ gdb --args clang++ testcase.cpp (gdb) set follow-fork-mode child (gdb) b SemaExpr.cpp:4981 (gdb) r Breakpoint 1 (gdb) p ParamType.dump() PointerType 0x6859c30 '__attribute__((__vector_size__(4 * sizeof(int)))) int volatile __dispatch *' `-QualType 0x6859c1c '__attribute__((__vector_size__(4 * sizeof(int)))) int volatile __dispatch' volatile __dispatch `-VectorType 0x68596e0 '__attribute__((__vector_size__(4 * sizeof(int)))) int' 4 `-BuiltinType 0x68590c0 'int'
(Where "__dispatch" is my target's name for address-space 109).
This dump demonstrates that the address space qualifier is on the pointee, not the pointer. The parameter is a of type "Pointer to (Address-Space-Qualified T)" rather than "(Address-Space-Qualified Pointer) to T."