
I had to revert https://github.com/llvm/llvm-project/pull/138205 in https://github.com/llvm/llvm-project/pull/141994 because it broke the Chrome build. The problem came down to the following: ```c++ unsigned __int64 _umul128(unsigned __int64, unsigned __int64, unsigned __int64 *); namespace {} #pragma intrinsic(_umul128) void foo() { unsigned __int64 carry; unsigned __int64 low = _umul128(0, 0, &carry); } ``` When processing the `#pragma intrinsic` line, we do a name lookup to see if the builtin was previously declared. In this case the lookup fails because the current namespace of the parser and sema is the above namespace scope. The processing of the pragma happens as part of the namespace close parsing. This is usually fine because most pragmas don't care about scopes. However, that's not true for this and other MS pragmas. To fix this, we change the `#pragma intrinsic` processing to be the same as other MS pragmas such as "optimize". Those are processed like a declaration, and because of that we have the correct current scope, so the lookup succeeds. I added a test case that locks down the Chrome fix, as well as manually tested the Chrome build and confirmed it passed.
33 lines
1.0 KiB
C++
33 lines
1.0 KiB
C++
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DOUTSIDE %s
|
|
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DINSIDE %s
|
|
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DNESTED %s
|
|
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DOUTSIDE -DEXTERN %s
|
|
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DINSIDE -DEXTERN %s
|
|
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fsyntax-only -verify -DNESTED -DEXTERN %s
|
|
|
|
// expected-no-diagnostics
|
|
#ifdef EXTERN
|
|
extern "C"
|
|
#endif
|
|
unsigned __int64 _umul128(unsigned __int64, unsigned __int64,
|
|
unsigned __int64 *);
|
|
namespace {
|
|
#ifdef INSIDE
|
|
#pragma intrinsic(_umul128)
|
|
#endif
|
|
#ifdef NESTED
|
|
namespace {
|
|
#pragma intrinsic(_umul128)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef OUTSIDE
|
|
#pragma intrinsic(_umul128)
|
|
#endif
|
|
|
|
void foo() {
|
|
unsigned __int64 carry;
|
|
unsigned __int64 low = _umul128(0, 0, &carry);
|
|
}
|