diff options
author | Eric Fiselier <eric@efcs.ca> | 2017-01-13 22:02:08 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2017-01-13 22:02:08 +0000 |
commit | ebaf7dab14c3bf1c4f995d9ad1199b6c2784a8ca (patch) | |
tree | f65c289da0bd7205d5042d29be1efd31a85b20d8 /test | |
parent | ccb58d0a2c539a5cec75a30f09243fd3064939a6 (diff) | |
download | external_libcxx-ebaf7dab14c3bf1c4f995d9ad1199b6c2784a8ca.tar.gz external_libcxx-ebaf7dab14c3bf1c4f995d9ad1199b6c2784a8ca.tar.bz2 external_libcxx-ebaf7dab14c3bf1c4f995d9ad1199b6c2784a8ca.zip |
Add _LIBCPP_DIAGNOSE_WARNING and _LIBCPP_DIAGNOSE_ERROR macros.
Clang recently added a `diagnose_if(cond, msg, type)` attribute
which can be used to generate diagnostics when `cond` is a constant
expression that evaluates to true. Otherwise no attribute has no
effect.
This patch adds _LIBCPP_DIAGNOSE_ERROR/WARNING macros which
use this new attribute. Additionally this patch implements
a diagnostic message when a non-const-callable comparator is
given to a container.
Note: For now the warning version of the diagnostic is useless
within libc++ since warning diagnostics are suppressed by the
system header pragma. I'm going to work on fixing this.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291961 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/libcxx/compiler.py | 4 | ||||
-rw-r--r-- | test/libcxx/containers/associative/non_const_comparator.fail.cpp | 45 | ||||
-rw-r--r-- | test/libcxx/test/config.py | 54 | ||||
-rw-r--r-- | test/libcxx/test/format.py | 4 | ||||
-rw-r--r-- | test/libcxx/utilities/tuple/tuple.tuple/diagnose_reference_binding.fail.cpp | 7 |
5 files changed, 86 insertions, 28 deletions
diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py index 8585f44ed..5003309a6 100644 --- a/test/libcxx/compiler.py +++ b/test/libcxx/compiler.py @@ -296,7 +296,7 @@ class CXXCompiler(object): def addWarningFlagIfSupported(self, flag): if self.hasWarningFlag(flag): - assert flag not in self.warning_flags - self.warning_flags += [flag] + if flag not in self.warning_flags: + self.warning_flags += [flag] return True return False diff --git a/test/libcxx/containers/associative/non_const_comparator.fail.cpp b/test/libcxx/containers/associative/non_const_comparator.fail.cpp new file mode 100644 index 000000000..239a7542f --- /dev/null +++ b/test/libcxx/containers/associative/non_const_comparator.fail.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: diagnose-if-support, verify-support + +// Test that libc++ generates a warning diagnostic when the container is +// provided a non-const callable comparator. + +#include <set> +#include <map> + +struct BadCompare { + template <class T, class U> + bool operator()(T const& t, U const& u) { + return t < u; + } +}; + +int main() { + static_assert(!std::__is_const_comparable<BadCompare, int>::value, ""); + // expected-warning@__tree:* 4 {{the specified comparator type does not provide a const call operator}} + { + using C = std::set<int, BadCompare>; + C s; + } + { + using C = std::multiset<long, BadCompare>; + C s; + } + { + using C = std::map<int, int, BadCompare>; + C s; + } + { + using C = std::multimap<long, int, BadCompare>; + C s; + } +} diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py index 5fcb8f4a9..bf17ab2f1 100644 --- a/test/libcxx/test/config.py +++ b/test/libcxx/test/config.py @@ -712,33 +712,35 @@ class Configuration(object): ['c++11', 'c++14', 'c++1z'])) != 0 enable_warnings = self.get_lit_bool('enable_warnings', default_enable_warnings) - if enable_warnings: - self.cxx.useWarnings(True) - self.cxx.warning_flags += [ - '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', - '-Wall', '-Wextra', '-Werror' - ] - self.cxx.addWarningFlagIfSupported('-Wshadow') - self.cxx.addWarningFlagIfSupported('-Wno-unused-command-line-argument') - self.cxx.addWarningFlagIfSupported('-Wno-attributes') - self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move') - self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions') - self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals') - # These warnings should be enabled in order to support the MSVC - # team using the test suite; They enable the warnings below and - # expect the test suite to be clean. - self.cxx.addWarningFlagIfSupported('-Wsign-compare') - self.cxx.addWarningFlagIfSupported('-Wunused-variable') - self.cxx.addWarningFlagIfSupported('-Wunused-parameter') - self.cxx.addWarningFlagIfSupported('-Wunreachable-code') - # FIXME: Enable the two warnings below. - self.cxx.addWarningFlagIfSupported('-Wno-conversion') + self.cxx.useWarnings(enable_warnings) + self.cxx.warning_flags += [ + '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', + '-Wall', '-Wextra', '-Werror' + ] + if self.cxx.hasWarningFlag('-Wuser-defined-warnings'): + self.cxx.warning_flags += ['-Wuser-defined-warnings'] + self.config.available_features.add('diagnose-if-support') + self.cxx.addWarningFlagIfSupported('-Wshadow') + self.cxx.addWarningFlagIfSupported('-Wno-unused-command-line-argument') + self.cxx.addWarningFlagIfSupported('-Wno-attributes') + self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move') + self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions') + self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals') + # These warnings should be enabled in order to support the MSVC + # team using the test suite; They enable the warnings below and + # expect the test suite to be clean. + self.cxx.addWarningFlagIfSupported('-Wsign-compare') + self.cxx.addWarningFlagIfSupported('-Wunused-variable') + self.cxx.addWarningFlagIfSupported('-Wunused-parameter') + self.cxx.addWarningFlagIfSupported('-Wunreachable-code') + # FIXME: Enable the two warnings below. + self.cxx.addWarningFlagIfSupported('-Wno-conversion') + self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef') + std = self.get_lit_conf('std', None) + if std in ['c++98', 'c++03']: + # The '#define static_assert' provided by libc++ in C++03 mode + # causes an unused local typedef whenever it is used. self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef') - std = self.get_lit_conf('std', None) - if std in ['c++98', 'c++03']: - # The '#define static_assert' provided by libc++ in C++03 mode - # causes an unused local typedef whenever it is used. - self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef') def configure_sanitizer(self): san = self.get_lit_conf('use_sanitizer', '').strip() diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py index cbd96f340..f267cab59 100644 --- a/test/libcxx/test/format.py +++ b/test/libcxx/test/format.py @@ -223,6 +223,10 @@ class LibcxxTestFormat(object): test_cxx.flags += ['-fsyntax-only'] if use_verify: test_cxx.useVerify() + test_cxx.useWarnings() + if '-Wuser-defined-warnings' in test_cxx.warning_flags: + test_cxx.warning_flags += ['-Wno-error=user-defined-warnings'] + cmd, out, err, rc = test_cxx.compile(source_path, out=os.devnull) expected_rc = 0 if use_verify else 1 if rc == expected_rc: diff --git a/test/libcxx/utilities/tuple/tuple.tuple/diagnose_reference_binding.fail.cpp b/test/libcxx/utilities/tuple/tuple.tuple/diagnose_reference_binding.fail.cpp index a35dfd696..c18822bbe 100644 --- a/test/libcxx/utilities/tuple/tuple.tuple/diagnose_reference_binding.fail.cpp +++ b/test/libcxx/utilities/tuple/tuple.tuple/diagnose_reference_binding.fail.cpp @@ -30,4 +30,11 @@ int main() { // bind rvalue to constructed non-rvalue std::tuple<std::string &&> t2("hello"); // expected-note {{requested here}} std::tuple<std::string &&> t3(std::allocator_arg, alloc, "hello"); // expected-note {{requested here}} + + // FIXME: The below warnings may get emitted as an error, a warning, or not emitted at all + // depending on the flags used to compile this test. + { + // expected-warning@tuple:* 0+ {{binding reference member 'value' to a temporary value}} + // expected-error@tuple:* 0+ {{binding reference member 'value' to a temporary value}} + } } |