@@ -1117,7 +1117,9 @@ pph_stream_unregister (pph_stream *stream)
/* Create a new PPH stream to be stored on the file called NAME.
- MODE is passed to fopen directly. */
+ MODE is passed to fopen directly. If NAME could not be opened,
+ return NULL to indicate to the caller that it should process NAME
+ as a regular text header. */
pph_stream *
pph_stream_open (const char *name, const char *mode)
@@ -1130,6 +1132,15 @@ pph_stream_open (const char *name, const char *mode)
stream = pph_stream_registry_lookup (name);
if (stream)
{
+ /* In a circular #include scenario, we will eventually try to
+ read from the same PPH image that we are generating. To
+ avoid that problem, detect circularity and return NULL to
+ force the caller to process NAME as a regular text header. */
+ if (stream->write_p && strchr (mode, 'r') != NULL)
+ return NULL;
+
+ /* Otherwise, assert that we have read (or are reading) STREAM
+ and return it. */
gcc_assert (stream->in_memory_p);
return stream;
}
@@ -41,6 +41,14 @@ exec echo "string.h string.pph" >> pph.map
set mapflag -fpph-map=pph.map
+# Remove all existing PPH images to prevent stale state issues.
+verbose "Removing existing PPH images" 0
+set pph_file_list "[glob -nocomplain *.pph]"
+foreach pph_file $pph_file_list {
+ remote_file build delete $pph_file
+}
+
+verbose "Running PPH tests" 0
foreach scenario $scenarios {
set old_dg_do_what_default "${dg-do-what-default}"
new file mode 100644
@@ -0,0 +1,8 @@
+#ifndef X1_CIRCULAR_H
+#define X1_CIRCULAR_H
+/* We are purposely generating a circular #include chain. Neither
+ header will be able to open the other one as their images are
+ being generated. */
+#include "x2circular.h" // { dg-warning "cannot open PPH file x2circular.pph.*" }
+int foo(int, int);
+#endif
new file mode 100644
@@ -0,0 +1,7 @@
+#ifndef X2_CIRCULAR_H
+#define X2_CIRCULAR_H
+int bar(int, int);
+
+#include "x1circular.h"
+
+#endif
new file mode 100644
@@ -0,0 +1,21 @@
+// { dg-do run }
+#include "x2circular.h"
+
+extern "C" { void abort(void); }
+
+int bar(int x, int y)
+{
+ return x - y;
+}
+
+int foo(int x, int y)
+{
+ return bar (x, y) + x + y;
+}
+
+int main(void)
+{
+ if (foo (0, 0) != 0)
+ abort ();
+ return 0;
+}