@@ -3238,6 +3238,8 @@ store::replay_call_summary_cluster (call_summary_replay &r,
caller_sval, NULL /* uncertainty_t * */);
}
break;
+
+ case RK_HEAP_ALLOCATED:
case RK_DECL:
{
const region *caller_dest_reg
@@ -3246,6 +3248,10 @@ store::replay_call_summary_cluster (call_summary_replay &r,
return;
const svalue *summary_sval
= summary.get_any_binding (mgr, summary_base_reg);
+ if (!summary_sval)
+ summary_sval = reg_mgr->get_or_create_compound_svalue
+ (summary_base_reg->get_type (),
+ summary_cluster->get_map ());
const svalue *caller_sval
= r.convert_svalue_from_summary (summary_sval);
if (!caller_sval)
@@ -3255,34 +3261,6 @@ store::replay_call_summary_cluster (call_summary_replay &r,
caller_sval, NULL /* uncertainty_t * */);
}
break;
- case RK_HEAP_ALLOCATED:
- {
- const region *caller_dest_reg
- = r.convert_region_from_summary (summary_base_reg);
- gcc_assert (caller_dest_reg);
- binding_cluster *caller_cluster
- = get_or_create_cluster (caller_dest_reg);
- auto_vec <const binding_key *> summary_keys;
- for (auto kv : *summary_cluster)
- summary_keys.safe_push (kv.first);
- summary_keys.qsort (binding_key::cmp_ptrs);
- for (auto summary_key : summary_keys)
- {
- const binding_key *caller_key
- = r.convert_key_from_summary (summary_key);
- if (!caller_key)
- continue;
- const svalue *summary_sval
- = summary_cluster->get_map ().get (summary_key);
- const svalue *caller_sval
- = r.convert_svalue_from_summary (summary_sval);
- if (!caller_sval)
- caller_sval = reg_mgr->get_or_create_unknown_svalue
- (summary_sval->get_type ());
- caller_cluster->bind_key (caller_key, caller_sval);
- }
- }
- break;
case RK_ALLOCA:
/* Ignore bindings of alloca regions in the summary. */
new file mode 100644
@@ -0,0 +1,108 @@
+/* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef struct _IO_FILE FILE;
+extern char *fgets(char *__restrict __s, int __n, FILE *__restrict __stream)
+ __attribute__((__access__(__write_only__, 1, 2)));
+extern void perror(const char *__s);
+enum {
+ _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)),
+};
+extern const unsigned short int **__ctype_b_loc(void)
+ __attribute__((__nothrow__, __leaf__)) __attribute__((__const__));
+extern void *malloc(size_t __size) __attribute__((__nothrow__, __leaf__))
+__attribute__((__malloc__)) __attribute__((__alloc_size__(1)));
+extern void exit(int __status) __attribute__((__nothrow__, __leaf__))
+__attribute__((__noreturn__));
+extern char *strcpy(char *__restrict __dest, const char *__restrict __src)
+ __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2)));
+extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__))
+__attribute__((__pure__)) __attribute__((__nonnull__(1)));
+
+struct mydata {
+ struct mydata *link;
+ char *name;
+ char *type;
+};
+
+static struct mydata *all_data;
+static int line_no;
+
+_Noreturn static void failed(const char *message) {
+ perror(message);
+ exit(1);
+}
+
+static char *string_dup(const char *string) {
+ char *buf;
+
+ if ((buf = malloc(strlen(string) + 1)) == ((void *)0))
+ failed("malloc() failed");
+
+ return strcpy(buf, string);
+}
+
+static void store_data(const char *name, const char *type) {
+ struct mydata *p, *q;
+
+ if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0))
+ failed("malloc() failed");
+
+ p->link = ((void *)0);
+ p->name = string_dup(name);
+ p->type = string_dup(type);
+
+ if ((q = all_data) == ((void *)0))
+ all_data = p;
+ else {
+ while (q->link != ((void *)0))
+ q = q->link;
+ q->link = p;
+ }
+}
+
+static void parse_tbl(char *buffer) {
+ char *s = buffer;
+ char *t = s + strlen(s);
+
+ do {
+ t--;
+ if (((*__ctype_b_loc())[(int)(((int)*t))] & (unsigned short int)_ISspace))
+ *t = '\0';
+ else
+ break;
+ } while (t > s);
+ while (((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace))
+ s++;
+ buffer = s;
+
+ line_no++;
+ if (*buffer != ';' && *buffer != '\0') {
+ if (*buffer == '#') {
+ store_data(buffer, ""); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */
+ } else {
+
+ while (*s && !((*__ctype_b_loc())[(int)(((int)*s))] &
+ (unsigned short int)_ISspace))
+ s++;
+ while (
+ ((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace))
+ *s++ = '\0';
+ store_data(buffer, s); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */
+ }
+ }
+}
+
+/* [...snip...] */
+
+static void makecfg(FILE *ifp, FILE *ofp, FILE *ofp2) {
+ char buffer[8192];
+
+ /* [...snip...] */
+
+ line_no = 0;
+ while (fgets(buffer, sizeof(buffer) - 1, ifp))
+ parse_tbl(buffer);
+
+ /* [...snip...] */
+}
I overreduced PR analyzer/107158 in r13-3096-gef878564140cbc, and there was another ICE in the original reproducer, which this patch fixes. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r13-3138-g629b4813e91aba. gcc/analyzer/ChangeLog: PR analyzer/107158 * store.cc (store::replay_call_summary_cluster): Eliminate special-casing of RK_HEAP_ALLOCATED in favor of sharing code with RK_DECL, avoiding an ICE due to attempting to bind a compound_svalue into a binding_cluster when an svalue in the summary cluster converts to a compound_svalue in the caller. gcc/testsuite/ChangeLog: PR analyzer/107158 * gcc.dg/analyzer/call-summaries-pr107158-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com> --- gcc/analyzer/store.cc | 34 +----- .../analyzer/call-summaries-pr107158-2.c | 108 ++++++++++++++++++ 2 files changed, 114 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c