]> granicus.if.org Git - clang/commit
[Modules] Implement __builtin_isinf_sign in Clang.
authorChandler Carruth <chandlerc@gmail.com>
Thu, 19 Mar 2015 22:39:51 +0000 (22:39 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Thu, 19 Mar 2015 22:39:51 +0000 (22:39 +0000)
commitf18d36bec8cefbf6aa4457a101189b7a8170439e
treedea0d9ed98661210cab38629032245f14a13cf0e
parentb2102bd391bcf0bd1f1b8ab33ad1551642d61308
[Modules] Implement __builtin_isinf_sign in Clang.

Somehow, we never managed to implement this fully. We could constant
fold it like crazy, including constant folding complex arguments, etc.
But if you actually needed to generate code for it, error.

I've implemented it using the somewhat obvious lowering. Happy for
suggestions on a more clever way to lower this.

Now, what you might ask does this have to do with modules? Fun story. So
it turns out that libstdc++ actually uses __builtin_isinf_sign to
implement std::isinf when in C++98 mode, but only inside of a template.
So if we're lucky, and we never instantiate that, everything is good.
But once we try to instantiate that template function, we need this
builtin. All of my customers at least are using C++11 and so they never
hit this code path.

But what does that have to do with modules? Fun story. So it turns out
that with modules we actually observe a bunch of bugs in libstdc++ where
their <cmath> header clobbers things exposed by <math.h>. To fix these,
we have to provide global function definitions to replace the macros
that C99 would have used. And it turns out that ::isinf needs to be
implemented using the exact semantics used by the C++98 variant of
std::isinf. And so I started to fix this bug in libstdc++ and ceased to
be able to compile libstdc++ with Clang.

The yaks are legion.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232778 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/CGBuiltin.cpp
test/CodeGen/builtins.c