--- /dev/null
+Various tests in this directory directly use the libstdc++ headers,
+providing an end-to-end test of the interaction of -fanalyzer and
+libstdc++ at various optimization levels.
+
+libstdc++-v3/doc/xml/manual/using.xml
+(https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html)
+notes that by default, glibcxx assertions are enabled at -O0, and
+disabled at -O1 and above.
+
+We will explicitly disable them in some tests via:
+ // { dg-additional-options "-D_GLIBCXX_NO_ASSERTIONS" }
+
+With optimizations, many tests simplify to be within the analyzer's
+normal limits, however at -O0 we may need to turn up
+ --param=analyzer-supernode-explosion-factor=
+for the analyzer to fully explore the code.
--- /dev/null
+/* Verify that the analyzer is silent on correct usage of std::string,
+ using <string>. */
+
+// { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } }
+
+/* Leaving assertions at default: we seem to need assertions at -O0
+ for the test to pass. */
+
+// { dg-additional-options "--param=analyzer-supernode-explosion-factor=10" }
+
+#include "../../../gcc.dg/analyzer/analyzer-decls.h"
+#include <string>
+
+void
+test_ctor_large ()
+{
+ std::string s {"0123456789012345678901234567890123456789"
+ "0123456789012345678901234567890123456789"};
+ __analyzer_eval (s.length () == 80); // { dg-warning "TRUE" }
+ __analyzer_eval (s.size () == 80); // { dg-warning "TRUE" }
+ __analyzer_eval (__builtin_strlen (s.c_str ()) == 80); // { dg-warning "TRUE" "ideal" { xfail *-*-* } }
+ // { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 }
+}
--- /dev/null
+/* Verify that the analyzer is silent on correct usage of std::string,
+ using <string>. */
+
+// { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } }
+
+/* Leaving assertions at default: we seem to need assertions at -O0
+ for the test to pass. */
+
+// { dg-additional-options "--param=analyzer-supernode-explosion-factor=10" }
+
+#include "../../../gcc.dg/analyzer/analyzer-decls.h"
+#include <string>
+
+void
+test_ctor_small ()
+{
+ std::string s {"abc"};
+ __analyzer_eval (s.length () == 3); // { dg-warning "TRUE" }
+ __analyzer_eval (s.size () == 3); // { dg-warning "TRUE" }
+ __analyzer_eval (__builtin_strlen (s.c_str ()) == 3); // { dg-warning "TRUE" "ideal" { xfail *-*-* } }
+ // { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 }
+}
--- /dev/null
+/* Verify that the analyzer is silent on correct usage of std::string,
+ using <string>. */
+
+// { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } }
+
+/* Leaving assertions at default: we seem to need assertions at -O0
+ for the test to pass. */
+
+#include "../../../gcc.dg/analyzer/analyzer-decls.h"
+#include <string>
+
+void
+test_ctor_empty ()
+{
+ std::string s;
+ __analyzer_eval (s.length () == 0); // { dg-warning "TRUE" }
+ __analyzer_eval (s.size () == 0); // { dg-warning "TRUE" }
+ __analyzer_eval (__builtin_strlen (s.c_str()) == 0); // { dg-warning "TRUE" }
+}
--- /dev/null
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+
+// { dg-additional-options "-D_GLIBCXX_NO_ASSERTIONS" }
+// { dg-additional-options "--param=analyzer-supernode-explosion-factor=10" }
+
+#include "../../../gcc.dg/analyzer/analyzer-decls.h"
+#include <memory>
+
+void
+test_null_deref_1 ()
+{
+ std::unique_ptr<int> p;
+ __analyzer_eval (*p == 42); // { dg-warning "null-dereference" }
+}
+
+void
+test_null_deref_2 ()
+{
+ auto p = std::make_unique<int> (42);
+ __analyzer_eval (*p == 42); // { dg-warning "TRUE" }
+ p = nullptr;
+ __analyzer_eval (*p); // { dg-warning "null-dereference" }
+}
+
+void
+test_use_after_free ()
+{
+ auto p = std::make_unique<int> (42);
+ __analyzer_eval (*p == 42); // { dg-warning "TRUE" }
+ int *ptr = p.get ();
+ p = nullptr;
+ __analyzer_eval (*ptr); // { dg-warning "use after 'delete'" }
+}