This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [rfc] atomic memory operation builtins
On Fri, Apr 08, 2005 at 05:40:45PM -0700, Mark Mitchell wrote:
> Be careful that works with templates in C++. In the case that none of
> the arguments are dependent, we should resolve the type up front; if
> they are dependent, then we should do it at instantiation time. I'd
> check that "sizeof (__sync... (/* something dependent */))" is *not*
> resolved at parse-time.
So... this seems like it'll be tricky. I'd thought it might be,
which is why I kept putting it off. ;-)
These sorts of builtins aren't overloaded in the way that the C++ FE
is used to dealing with type-dependent things. For example:
void f(long) { exit(0); }
void f(int) { abort(); }
template<typename T>
void g(T *p)
{
f(__sync_lock_test_and_set (p, 1));
}
main()
{
long x;
g(&x);
}
So we can easily decide that P is type-dependent, and thus we should
not immediately resolve the call to __sync_lock_test_and_set. However,
the type of the node for __sync_lock_test_and_set is not such that it
appears to be type-dependent, so we're going to try to resolve the call
to f immediately. And fail.
Suggestions?
Is there some type node I could create and use statically when
constructing __sync_lock_test_and_set?
Should I wrap this in a cast operation to __typeof(*p)? That would
certainly let the surrounding code know the correct type, but might
also require "interesting" hackery in the template expander later.
You'd also wind up with intermediate code that appears to be junk,
if you care about such things from the browsing point of view.
I could add a bit to the FUNCTION_DECL that indicates that the
builtin is overloaded; that might ameliorate the junk intermediate
code problem, as well as make it easier to figure out when to apply
this sort of transformation.
r~