2020-01-26 Jason Merrill <jason@redhat.com>
+ PR c++/90992
+ * except.c (maybe_noexcept_warning): Check DECL_IN_SYSTEM_HEADER and
+ temporarily enable -Wsystem-headers. Change second warning to
+ conditional inform.
+
PR c++/90997
* semantics.c (finish_call_expr): Don't call
instantiate_non_dependent_expr before warn_for_memset.
static void
maybe_noexcept_warning (tree fn)
{
- if (TREE_NOTHROW (fn))
+ if (TREE_NOTHROW (fn)
+ && (!DECL_IN_SYSTEM_HEADER (fn)
+ || global_dc->dc_warn_system_headers))
{
- warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
- "because of a call to %qD", fn);
- warning_at (DECL_SOURCE_LOCATION (fn), OPT_Wnoexcept,
- "but %qD does not throw; perhaps "
- "it should be declared %<noexcept%>", fn);
+ temp_override<bool> s (global_dc->dc_warn_system_headers, true);
+ auto_diagnostic_group d;
+ if (warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
+ "because of a call to %qD", fn))
+ inform (DECL_SOURCE_LOCATION (fn),
+ "but %qD does not throw; perhaps "
+ "it should be declared %<noexcept%>", fn);
}
}
--- /dev/null
+// PR c++/90992
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -Wnoexcept }
+
+#include "Wnoexcept1.h"
+
+// We expect a warning at the declaration of construct2, since Automatic2 is
+// defined below; we don't expect one for construct1, because Automatic1 is
+// defined in the fake system header.
+// { dg-warning "noexcept-expression" "" { target *-*-* } 26 }
+
+class Automatic2 {
+public:
+ Automatic2(size_t bla) : Bla(bla) {}; // { dg-message "noexcept" }
+
+private:
+ size_t Bla;
+ NotNoexcept Dummy;
+};
+
+union U
+{
+ unsigned char buf[sizeof(Automatic1)];
+ Automatic1 a1;
+ Automatic2 a2;
+ U(): buf{} {}
+ ~U() {}
+};
+
+int main() {
+ U u;
+ construct1(&u.a1, 42);
+ construct2(&u.a2, 42);
+}
--- /dev/null
+// -*- C++ -*-
+#pragma GCC system_header
+
+using size_t = decltype(sizeof(42));
+inline void * operator new (size_t, void *p) noexcept { return p; }
+
+class NotNoexcept {
+public:
+ NotNoexcept() noexcept(false) {}
+ NotNoexcept(const NotNoexcept&) noexcept(false) {}
+ NotNoexcept(NotNoexcept &&) noexcept(false) {}
+ ~NotNoexcept() noexcept(false) {}
+
+ NotNoexcept&operator=(const NotNoexcept&) noexcept(false) { return *this;}
+ NotNoexcept&operator=(NotNoexcept &&) noexcept(false) {return *this;}
+};
+
+template<typename _Up, typename... _Args>
+void
+construct1(_Up* __p, _Args... __args)
+ noexcept(noexcept(::new((void *)__p) _Up(__args...)))
+{ ::new((void *)__p) _Up(__args...); }
+
+template<typename _Up, typename... _Args>
+void
+construct2(_Up* __p, _Args... __args)
+ noexcept(noexcept(::new((void *)__p) _Up(__args...)))
+{ ::new((void *)__p) _Up(__args...); }
+
+class Automatic1 {
+public:
+ Automatic1(size_t bla) : Bla(bla) {};
+
+private:
+ size_t Bla;
+ NotNoexcept Dummy;
+};