Add test and mitigation for clang 11 compiler bug (#27073)

* Add test and mitigation for clang 11 compiler bug

* document

* document

* Automated change: Fix sanity tests

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/27123/head
Craig Tiller 3 years ago committed by GitHub
parent df3a13a2a3
commit 46afdf9989
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 35
      CMakeLists.txt
  2. 9
      build_autogenerated.yaml
  3. 11
      include/grpc/impl/codegen/port_platform.h
  4. 31
      test/core/compiler_bugs/BUILD
  5. 58
      test/core/compiler_bugs/miscompile_with_no_unique_address_test.cc
  6. 24
      tools/run_tests/generated/tests.json

35
CMakeLists.txt generated

@ -910,6 +910,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx match_test)
add_dependencies(buildtests_cxx matchers_test)
add_dependencies(buildtests_cxx message_allocator_end2end_test)
add_dependencies(buildtests_cxx miscompile_with_no_unique_address_test)
add_dependencies(buildtests_cxx mock_stream_test)
add_dependencies(buildtests_cxx mock_test)
add_dependencies(buildtests_cxx nonblocking_test)
@ -12705,6 +12706,40 @@ target_link_libraries(message_allocator_end2end_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(miscompile_with_no_unique_address_test
test/core/compiler_bugs/miscompile_with_no_unique_address_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(miscompile_with_no_unique_address_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(miscompile_with_no_unique_address_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
)
endif()
if(gRPC_BUILD_TESTS)

@ -5955,6 +5955,15 @@ targets:
- test/cpp/end2end/test_service_impl.cc
deps:
- grpc++_test_util
- name: miscompile_with_no_unique_address_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/compiler_bugs/miscompile_with_no_unique_address_test.cc
deps: []
uses_polling: false
- name: mock_stream_test
gtest: true
build: test

@ -684,4 +684,15 @@ typedef unsigned __int64 uint64_t;
#define GRPC_CALLBACK_API_NONEXPERIMENTAL
/* clang 11 with msan miscompiles destruction of [[no_unique_address]] members
* of zero size - for a repro see:
* test/core/compiler_bugs/miscompile_with_no_unique_address_test.cc
*/
#ifdef __clang__
#if __clang__ && __clang_major__ <= 11 && __has_feature(memory_sanitizer)
#undef GPR_NO_UNIQUE_ADDRESS
#define GPR_NO_UNIQUE_ADDRESS
#endif
#endif
#endif /* GRPC_IMPL_CODEGEN_PORT_PLATFORM_H */

@ -0,0 +1,31 @@
# Copyright 2021 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package")
licenses(["notice"])
grpc_package(name = "test/core/compiler_bugs")
grpc_cc_test(
name = "miscompile_with_no_unique_address_test",
srcs = ["miscompile_with_no_unique_address_test.cc"],
external_deps = ["gtest"],
language = "c++",
uses_polling = False,
deps = [
"//:gpr_platform",
"//test/core/util:grpc_suppressions",
],
)

@ -0,0 +1,58 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/impl/codegen/port_platform.h>
#include <gtest/gtest.h>
// Make a template argument to test which bit pattern remains in A's destructor
// to try and detect similar bugs in non-MSAN builds (none have been detected
// yet thankfully)
template <int kInit>
class A {
public:
~A() { EXPECT_EQ(a_, kInit); }
int a_ = kInit;
};
template <class T, int kInit>
class P : A<kInit> {
public:
explicit P(T b) : b_(b) {}
// clang 11 with MSAN miscompiles this and marks A::a_ as uninitialized during
// P::~P() if GPR_NO_UNIQUE_ADDRESS is [[no_unique_address]] - so this test
// stands to ensure that we have a working definition for this compiler so
// that we don't flag false negatives elsewhere in the codebase.
GPR_NO_UNIQUE_ADDRESS T b_;
};
template <int kInit, class T>
void c(T a) {
P<T, kInit> _(a);
}
TEST(Miscompile, Zero) {
c<0>([] {});
}
TEST(Miscompile, One) {
c<1>([] {});
}
TEST(Miscompile, MinusOne) {
c<-1>([] {});
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

@ -5513,6 +5513,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "miscompile_with_no_unique_address_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save