From 5cfebb0f904131d1df8e36fcb9c290f12c06e9ba Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 9 Feb 2016 11:24:47 -0500 Subject: [PATCH] RunClang: Avoid GNU extensions in glibc math headers on i386 On i386 with optimizations enabled, the `bits/mathinline.h` header may use a GNU extension not implemented by Clang. Avoid parsing this code by defining `__NO_MATH_INLINES` so it will be preprocessed out. GitHub-Issue: #47 --- src/RunClang.cxx | 14 ++++++++++++++ test/CMakeLists.txt | 2 ++ test/expect/cmd.cc-gnu-c-tgt-i386-opt-E.stdout.txt | 11 +++++++++++ test/expect/cmd.cc-gnu-tgt-i386-opt-E.stdout.txt | 12 ++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 test/expect/cmd.cc-gnu-c-tgt-i386-opt-E.stdout.txt create mode 100644 test/expect/cmd.cc-gnu-tgt-i386-opt-E.stdout.txt diff --git a/src/RunClang.cxx b/src/RunClang.cxx index 9768a25..0a68698 100644 --- a/src/RunClang.cxx +++ b/src/RunClang.cxx @@ -204,6 +204,13 @@ class CastXMLPredefines: public T } } + // Prevent glibc use of a GNU extension not implemented by Clang. + if (this->NeedNoMathInlines(this->Opts.Predefines)) { + builtins += "\n" + "#define __NO_MATH_INLINES 1\n" + ; + } + } else { builtins += predefines.substr(start, end-start); } @@ -229,6 +236,13 @@ class CastXMLPredefines: public T pd.find("#define __ia64__ ") != pd.npos)); } + bool NeedNoMathInlines(std::string const& pd) const { + return (this->IsActualGNU(pd) && + (pd.find("#define __i386__ ") != pd.npos && + pd.find("#define __OPTIMIZE__ ") != pd.npos && + pd.find("#define __NO_MATH_INLINES ") == pd.npos)); + } + bool BeginSourceFileAction(clang::CompilerInstance& CI, llvm::StringRef /*Filename*/) { CI.getPreprocessor().setPredefines(this->UpdatePredefines(CI)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e13d308..9ed4a50 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -205,6 +205,7 @@ castxml_test_cmd(cc-gnu-src-cxx-cmd --castxml-cc-gnu $ ${emp castxml_test_cmd(cc-gnu-tgt-amd64 --castxml-cc-gnu "(" $ --cc-define=__amd64__ ")" ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-explicit --castxml-cc-gnu "(" $ ")" -target explicit-target-triple ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-i386 --castxml-cc-gnu "(" $ --cc-define=__i386__ ")" ${empty_cxx} "-###") +castxml_test_cmd(cc-gnu-tgt-i386-opt-E --castxml-cc-gnu "(" $ --cc-define=__i386__ --cc-define=__OPTIMIZE__ ")" ${empty_cxx} -E -dM) castxml_test_cmd(cc-gnu-tgt-mingw --castxml-cc-gnu "(" $ --cc-define=_WIN32 --cc-define=__MINGW32__ ")" ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-win --castxml-cc-gnu "(" $ --cc-define=_WIN32 ")" ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-x86_64 --castxml-cc-gnu "(" $ --cc-define=__x86_64__ ")" ${empty_cxx} "-###") @@ -224,6 +225,7 @@ castxml_test_cmd(cc-gnu-c-std-c11 --castxml-cc-gnu-c "(" $ - castxml_test_cmd(cc-gnu-c-std-gnu89 --castxml-cc-gnu-c "(" $ ")" ${empty_c} "-###") castxml_test_cmd(cc-gnu-c-std-gnu99 --castxml-cc-gnu-c "(" $ -std=199901L ")" ${empty_c} "-###") castxml_test_cmd(cc-gnu-c-std-gnu11 --castxml-cc-gnu-c "(" $ -std=201112L ")" ${empty_c} "-###") +castxml_test_cmd(cc-gnu-c-tgt-i386-opt-E --castxml-cc-gnu-c "(" $ --cc-define=__i386__ --cc-define=__OPTIMIZE__ ")" ${empty_c} -E -dM) # Test --castxml-cc-msvc detection. add_executable(cc-msvc cc-msvc.c) diff --git a/test/expect/cmd.cc-gnu-c-tgt-i386-opt-E.stdout.txt b/test/expect/cmd.cc-gnu-c-tgt-i386-opt-E.stdout.txt new file mode 100644 index 0000000..865095d --- /dev/null +++ b/test/expect/cmd.cc-gnu-c-tgt-i386-opt-E.stdout.txt @@ -0,0 +1,11 @@ +^#define __GNUC_MINOR__ 1 +#define __GNUC__ 1 +#define __NO_MATH_INLINES 1 +#define __OPTIMIZE__ 1 +#define __builtin_va_arg_pack\(\) 0 +#define __builtin_va_arg_pack_len\(\) 1 +#define __castxml__ [0-9]+ +#define __castxml_clang_major__ [0-9]+ +#define __castxml_clang_minor__ [0-9]+ +#define __castxml_clang_patchlevel__ [0-9]+ +#define __i386__ 1$ diff --git a/test/expect/cmd.cc-gnu-tgt-i386-opt-E.stdout.txt b/test/expect/cmd.cc-gnu-tgt-i386-opt-E.stdout.txt new file mode 100644 index 0000000..fa9c1e5 --- /dev/null +++ b/test/expect/cmd.cc-gnu-tgt-i386-opt-E.stdout.txt @@ -0,0 +1,12 @@ +^#define __GNUC_MINOR__ 1 +#define __GNUC__ 1 +#define __NO_MATH_INLINES 1 +#define __OPTIMIZE__ 1 +#define __builtin_va_arg_pack\(\) 0 +#define __builtin_va_arg_pack_len\(\) 1 +#define __castxml__ [0-9]+ +#define __castxml_clang_major__ [0-9]+ +#define __castxml_clang_minor__ [0-9]+ +#define __castxml_clang_patchlevel__ [0-9]+ +#define __cplusplus 199711L +#define __i386__ 1$