diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index e7829a461bbc5..8f33c798290bd 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -14,8 +14,10 @@ #include "BuiltinTargetFeatures.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangStandard.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringTable.h" using namespace clang; const char *HeaderDesc::getName() const { @@ -135,6 +137,24 @@ bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) { return false; } +static bool isSymbolAvailableInC89(const llvm::StringTable &Strings, + const Builtin::Info &BuiltinInfo) { + + auto NameStr = Strings[BuiltinInfo.Offsets.Name]; + + if (NameStr.starts_with("__builtin_")) { + return true; + } + + // FIXME: add other C89 symbols here + if (NameStr == "log" || NameStr == "va_start" || NameStr == "va_arg" || + NameStr == "va_end") { + return true; + } + + return false; +} + /// Is this builtin supported according to the given language options? static bool builtinIsSupported(const llvm::StringTable &Strings, const Builtin::Info &BuiltinInfo, @@ -147,6 +167,11 @@ static bool builtinIsSupported(const llvm::StringTable &Strings, /* CorBuiltins Unsupported */ if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG)) return false; + bool isC89 = /*C89*/ LangOpts.LangStd == LangStandard::lang_c89; + if (isC89 && BuiltinInfo.Header.ID != BuiltinInfo.Header.NO_HEADER && + !isSymbolAvailableInC89(Strings, BuiltinInfo)) { + return false; + } /* MathBuiltins Unsupported */ if (LangOpts.NoMathBuiltin && BuiltinInfo.Header.ID == HeaderDesc::MATH_H) return false; diff --git a/clang/test/C/drs/c89_with_c99_functions.c b/clang/test/C/drs/c89_with_c99_functions.c new file mode 100644 index 0000000000000..aa3672eda1c53 --- /dev/null +++ b/clang/test/C/drs/c89_with_c99_functions.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c89 -verify=c89 %s + +// From: https://github.com/llvm/llvm-project/issues/15522#issue-1071059939 +int logf = 5; // this is fine + +// redefinition because log as a symbol exists in C89 +int log = 6; // #1 +int main() { +return 0; +} + +// c89-error@#1 {{redefinition of 'log' as different kind of symbol}} +// c89-note@#1 {{unguarded header; consider using #ifdef guards or #pragma once}} +// c89-note@#1 {{previous definition}}