diff -ur src.orig/configure src/configure --- src.orig/configure Sun Apr 15 00:10:13 2007 +++ src/configure Wed Dec 19 00:25:04 2007 @@ -3412,13 +3412,13 @@ CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g -O2" + CFLAGS="-g3" else - CFLAGS="-g" + CFLAGS="-g3" fi else if test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="" else CFLAGS= fi @@ -3919,13 +3919,13 @@ CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then - CXXFLAGS="-g -O2" + CXXFLAGS="-g3" else - CXXFLAGS="-g" + CXXFLAGS="-g3" fi else if test "$GXX" = yes; then - CXXFLAGS="-O2" + CXXFLAGS="" else CXXFLAGS= fi Only in src/: configure~ diff -ur src.orig/gcc/Makefile.in src/gcc/Makefile.in --- src.orig/gcc/Makefile.in Sun Apr 15 00:14:12 2007 +++ src/gcc/Makefile.in Wed Dec 19 00:25:34 2007 @@ -531,7 +531,7 @@ # Options to use when compiling libgcc2.a. # LIBGCC2_DEBUG_CFLAGS = -g -LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \ +LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \ $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \ -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \ $(INHIBIT_LIBC_CFLAGS) @@ -544,7 +544,7 @@ TARGET_LIBGCC2_CFLAGS = # Options to use when compiling crtbegin/end. -CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ +CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline-functions -fno-exceptions \ -fno-zero-initialized-in-bss -fno-toplevel-reorder \ $(INHIBIT_LIBC_CFLAGS) Only in src/gcc: Makefile.in~ diff -ur src.orig/gcc/condate.y src/gcc/condate.y --- src.orig/gcc/condate.y Sun Apr 15 00:14:55 2007 +++ src/gcc/condate.y Sun Jan 13 16:49:20 2008 @@ -49,7 +49,10 @@ #include "tree-match.h" int yylex (void); void yyerror (char const *); - + pattern frompat, topat, avoidpat, matchpat, functionpat, followpat; + char *types; + static int line = 0; + static int fromappearatleastonce = 0; %} /* Bison declarations. */ @@ -57,29 +60,58 @@ %token CONDATE %token FROM %token TO +%token FOLLOW %token AVOID +%token MATCH %token IDENT %right OR %token STR %token CCODE %token WARNING +%token TYPES +%token FUNCTIONS +%token FROMAPPEARONCE %% /* The grammar follows. */ start: /* empty */ -| start condate {/* print_cond($2); */ - normalize_condate($2); - name_condate($2); - add_condate($2);}; +| start {frompat = topat = functionpat = avoidpat = matchpat = followpat = NULL; + fromappearatleastonce = 0; types = NULL;}condate { + normalize_condate($3); + name_condate($3); + add_condate($3);}; condate: CONDATE IDENT '{' crq '}' WARNING '(' STR ')' ';' {$$ = $4; ((condate)$$)->name = $2; ((condate)$$)->msg = $8;} | crq ';' {$$ = $1;}; -/* Constraint Reachability Queries */ -crq: patexp {$$ = mkcond(NULL, $1, NULL, NULL, NULL, NULL);} -| FROM patexp TO patexp {$$ = mkcond(NULL, $2, $4, NULL, NULL, NULL);} -| FROM patexp TO patexp AVOID patexp {$$ = mkcond(NULL, $2, $4, $6, NULL, NULL);}; +crq: crqelements +{if (frompat == NULL || topat == NULL) + fprintf(stderr, "You should at least supply from pattern and to pattern\n"); + $$ = mkcond (NULL, frompat, topat, avoidpat, NULL, NULL, matchpat, types, functionpat, + followpat, fromappearatleastonce);}; + +crqelements: +|crqelements crqelement; + +crqelement: +FROM patexp { if(frompat)fprintf(stderr,"%s:%d duplicate from pattern!\n",tree_check_file,line); + else frompat = $2; } +|TO patexp { if(topat)fprintf(stderr,"%s:%d duplicate to pattern\n",tree_check_file,line); + else topat = $2;} +|AVOID patexp{if(avoidpat)fprintf(stderr,"%s:%d duplicate avoid pattern\n",tree_check_file,line); + else avoidpat = $2;} +|MATCH patexp {if(matchpat)fprintf(stderr,"%s:%d duplicate match pattern\n",tree_check_file,line); + else matchpat = $2;} +|FOLLOW patexp {if(followpat)fprintf(stderr,"%s:%d duplicate match pattern\n",tree_check_file,line); else followpat = $2;} +|TYPES STR { if(types)fprintf(stderr,"%s:%d duplicate types declaration\n",tree_check_file,line); + else types = $2;} +|FUNCTIONS patexp + {if(functionpat)fprintf(stderr,"%s:%d duplicate function pattern\n",tree_check_file,line); + else functionpat = $2;} +|FROMAPPEARONCE {fromappearatleastonce = 1;} +; + patexp: edgepat {$$ = $1;} | patexp OR patexp {$$ = pat_or($1, $3);} @@ -124,14 +156,19 @@ /* Skip white space and comments. */ do { - while (c == ' ' || c == '\t' || c == '\n') + while (c == ' ' || c == '\t' || c == '\n') { + if (c == '\n') + line++; c = getc (checkfile); + } if(c == '#') { while ((c = getc (checkfile)) != '\n' && c != EOF) ; - if (c == '\n') + if (c == '\n') { + line++; c = getc (checkfile); + } } } while(c == ' ' || c == '\t' || c == '#' || c == '\n'); @@ -205,12 +242,22 @@ return FROM; else if (!strcmp (buf, "to")) return TO; + else if (!strcmp (buf, "match")) + return MATCH; + else if (!strcmp (buf, "follow")) + return FOLLOW; else if (!strcmp (buf, "avoid")) return AVOID; else if (!strcmp (buf, "or")) return OR; else if (!strcmp (buf, "warning")) return WARNING; + else if (!strcmp (buf, "types")) + return TYPES; + else if (!strcmp (buf, "functions")) + return FUNCTIONS; + else if (!strcmp (buf, "fromappearatleastonce")) + return FROMAPPEARONCE; /* identifier */ yylval = xstrdup (buf); return IDENT; @@ -228,8 +275,8 @@ char buf[32]; fprintf (stderr, "%s: %s\n", tree_check_file, s); fgets (buf, 32, checkfile); - fprintf (stderr, "%s: before or near: \"%s\"\n", - tree_check_file, buf); + fprintf (stderr, "%s: before or near: \"%s\" on line %d\n", + tree_check_file, buf, line); } struct split_pattern_s split_pattern(pattern p); Only in src/gcc: condate.y.back Only in src/gcc: condate.y~ diff -ur src.orig/gcc/diagnostic.h src/gcc/diagnostic.h --- src.orig/gcc/diagnostic.h Sun Apr 15 00:13:07 2007 +++ src/gcc/diagnostic.h Thu Jan 3 11:09:23 2008 @@ -217,6 +217,8 @@ extern void print_generic_decl (FILE *, tree, int); extern VEC (tree_chunk, heap) *lazy_dump_generic_node (tree, int, bool); +extern VEC (tree_chunk, heap) *nolazy_dump_generic_node (tree, int, bool); + extern void lazy_print_generic_expr (FILE *file, tree t, int flags); extern void debug_generic_expr (tree); Only in src/gcc: diagnostic.h~ diff -ur src.orig/gcc/passes.c src/gcc/passes.c --- src.orig/gcc/passes.c Sun Apr 15 00:14:19 2007 +++ src/gcc/passes.c Mon Dec 24 09:45:29 2007 @@ -451,7 +451,7 @@ NEXT_PASS (pass_lower_cf); NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_build_cfg); - NEXT_PASS (pass_check); +// NEXT_PASS (pass_check); NEXT_PASS (pass_lower_complex_O0); NEXT_PASS (pass_lower_vector); NEXT_PASS (pass_warn_function_return); @@ -645,6 +645,7 @@ NEXT_PASS (pass_mark_used_blocks); NEXT_PASS (pass_cleanup_cfg_post_optimizing); } + NEXT_PASS (pass_check); NEXT_PASS (pass_warn_function_noreturn); NEXT_PASS (pass_free_datastructures); NEXT_PASS (pass_mudflap_2); Only in src/gcc: passes.c~ Only in src/gcc: tree-cfg.c~ diff -ur src.orig/gcc/tree-check.c src/gcc/tree-check.c --- src.orig/gcc/tree-check.c Sun Apr 15 00:14:58 2007 +++ src/gcc/tree-check.c Sat Jan 19 15:03:21 2008 @@ -120,25 +120,153 @@ return 1; /* follow_all */ } +static int +check_node1 (cfg_node node, condate cond) +{ + tree stmt = cfg_node_stmt (node); + + if (!stmt || TREE_VISITED (stmt)) + return 0; + + TREE_VISITED (stmt) = 1; + + + if (tree_match_disj (stmt, cond->to, node)) + { + return 2; /* follow_none */ + } + + + if (cond->avoid && tree_match_disj (stmt, cond->avoid, node)) + { +/* tree_check_warning (cond, stmt, OPT_ftree_checks_);*/ + return -1; /* follow_none */; + } + else + return 1; /* follow_all */ +} + + +static int +check_node2 (cfg_node node, condate cond, int matchstage) +{ + tree stmt = cfg_node_stmt (node); + + if (!stmt || TREE_VISITED (stmt)) + return 0; + + + TREE_VISITED (stmt) = 1; + + + if (tree_match_disj (stmt, cond->to, node)) + { + VEC (cfg_node, heap) *follow = VEC_alloc (cfg_node, heap, 100); + VEC (tree, heap) *stmts = VEC_alloc(tree, heap, 200); + VEC_safe_push(cfg_node, heap, follow, node); + TREE_VISITED(stmt) = 0; + int followmatch = 0; + while (VEC_length (cfg_node, follow) != 0) { + tree stmt1; + cfg_node node1, succ_node; + node1 = VEC_pop (cfg_node, follow); + stmt1 = cfg_node_stmt (node1); + if (!stmt1 || stmt1->base.spare == 2) + continue; + VEC_safe_push(tree, heap, stmts, (tree)stmt1->base.spare); + VEC_safe_push(tree, heap, stmts, stmt1); + stmt1->base.spare = 2; + + if (tree_match_disj (stmt1, cond->follow, node1)) + { + if (cond->fromappearatleastonce == 0 && !matchstage) + tree_check_warning (cond, stmt, OPT_ftree_checks_); + followmatch = 1; + break; + } + if (node1->next == NULL) + { + edge e; + edge_iterator ei; + basic_block bb; + bb = bb_for_stmt (stmt1); + FOR_EACH_EDGE (e, ei, bb->succs) + { + if (e->dest == EXIT_BLOCK_PTR) + continue; + succ_node = bb_1st_cfg_node (e->dest); + VEC_safe_push (cfg_node, heap, follow, succ_node); + } + } else { + succ_node = node1->next; + VEC_safe_push (cfg_node, heap, follow, succ_node); + } + } + while (VEC_length (tree, stmts) != 0) { + tree stmt1; + stmt1 = VEC_pop (tree, stmts); + stmt1->base.spare = (int )VEC_pop(tree, stmts); + } + if (!matchstage) + TREE_VISITED(stmt) = 1; + VEC_free (cfg_node, heap, follow); + VEC_free (tree, heap, stmts); + if (followmatch) + return 2; + else + return 0; + } + + if (matchstage) + return 0; + + if (cond->avoid && tree_match_disj (stmt, cond->avoid, node)) + { + return -1; /* follow_none */; + } + else + return 1; /* follow_all */ +} + + + /* Check a condate instance over the CFG of the current function. */ -static void +static int tree_check_instance (condate cond) { VEC (cfg_node, heap) *stack = VEC_alloc (cfg_node, heap, 100); basic_block bb; cfg_node node; tree stmt; + int checkedonce = 0; + PP_TRACE (TRACE_CHECK, { fprintf (stderr, "checking condate instance:\n"); print_global_holes (); }); + /* Push from nodes on the stack. */ PP_TRACE (TRACE_CHECK, fprintf (stderr, "searching src pat %s\n", cond->from->format_spec)); + if (!strncmp(cond->from->format_spec, "entry", 5)){ + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) + { + if (e->dest == EXIT_BLOCK_PTR) + continue; + node = bb_1st_cfg_node (e->dest); + stmt = cfg_node_stmt (node); + if (stmt) + TREE_VISITED (stmt) = 1; + VEC_safe_push (cfg_node, heap, stack, node); + } + } else { + FOR_EACH_BB (bb) { block_stmt_iterator bsi; @@ -172,10 +300,62 @@ print_generic_expr (stderr, stmt, 0); fprintf (stderr, "\n"); }); - } + } else if (bsi_cfg_node (bsi)->next == NULL && + TREE_CODE(stmt) == COND_EXPR) { + edge e; + edge_iterator ei; + basic_block bb; + bb = bb_for_stmt(stmt); + node = bsi_cfg_node (bsi); + + FOR_EACH_EDGE(e, ei, bb->succs) + { + if (e->flags&EDGE_TRUE_VALUE) { + pattern patttmp = patt; + while (patttmp) { + if (patttmp->sign == 1 && + (tree_match_prevstmt(COND_EXPR_COND (stmt), + patttmp->format_spec, node)|| + tree_match(COND_EXPR_COND(stmt), + patttmp->format_spec, node))) + { + tree stmt1; + cfg_node succ_node; + succ_node = bb_1st_cfg_node (e->dest); + stmt1 = cfg_node_stmt (succ_node); + VEC_safe_push (cfg_node, heap, stack, succ_node); + if (stmt1) + TREE_VISITED (stmt1) = 1; + } + patttmp = patttmp->next; + } + } + if (e->flags&EDGE_FALSE_VALUE) { + pattern patttmp = patt; + while (patttmp) { + if (patttmp->sign == -1 && + (tree_match_prevstmt(COND_EXPR_COND (stmt), + patttmp->format_spec, node)|| + tree_match(COND_EXPR_COND(stmt), + patttmp->format_spec, node))) + { + tree stmt1; + cfg_node succ_node; + succ_node = bb_1st_cfg_node (e->dest); + stmt1 = cfg_node_stmt (succ_node); + VEC_safe_push (cfg_node, heap, stack, succ_node); + if (stmt1) + TREE_VISITED (stmt1) = 1; + } + patttmp = patttmp->next; + } + } + + } } - } - + } + } + } PP_TRACE (TRACE_CHECK, fprintf (stderr, "%d src stmts found\n", (unsigned) VEC_length (cfg_node, stack))); @@ -201,43 +381,119 @@ continue; if (TREE_CODE (stmt) == COND_EXPR - && (e->flags & EDGE_TRUE_VALUE && cond->avoid_then - && tree_match_disj (COND_EXPR_COND (stmt), cond->avoid_then, - node))) + && (e->flags & EDGE_TRUE_VALUE && cond->avoid_then)) { - PP_TRACE (TRACE_CHECK, - fprintf (stderr, "via-then edge, skipping\n")); - continue; + if( tree_match_disj (COND_EXPR_COND (stmt), cond->avoid_then, + node)) + { + PP_TRACE (TRACE_CHECK, + fprintf (stderr, "via-then edge, skipping\n")); + continue; + } else if (node->prev && tree_match_prevstmt_disj(COND_EXPR_COND (stmt), + cond->avoid_then, node)) + { + PP_TRACE (TRACE_CHECK, + fprintf (stderr, "via-then edge, skipping\n")); + continue; + } } + if (TREE_CODE (stmt) == COND_EXPR - && (e->flags & EDGE_FALSE_VALUE && cond->avoid_else - && tree_match_disj (COND_EXPR_COND (stmt), cond->avoid_else, - node))) + && (e->flags & EDGE_FALSE_VALUE && cond->avoid_else)) { - PP_TRACE (TRACE_CHECK, + if (tree_match_disj (COND_EXPR_COND (stmt), cond->avoid_else, + node)) + { + PP_TRACE (TRACE_CHECK, fprintf (stderr, "via-else edge, skipping\n")); - continue; + continue; + } else if (node->prev && tree_match_prevstmt_disj(COND_EXPR_COND (stmt), + cond->avoid_else, node)) + { + PP_TRACE (TRACE_CHECK, + fprintf (stderr, "via-then edge, skipping\n")); + continue; + } } succ_node = bb_1st_cfg_node (e->dest); - push_it = check_node (succ_node, cond); - if (push_it) - VEC_safe_push (cfg_node, heap, stack, succ_node); - } + if (cond->fromappearatleastonce == 0 && cond->follow == NULL) { + push_it = check_node (succ_node, cond); + if (push_it) + VEC_safe_push (cfg_node, heap, stack, succ_node); + }else if (cond->follow == NULL) { + switch (check_node1(succ_node, cond)) + { + case 1: + VEC_safe_push (cfg_node, heap, stack, succ_node); + break; + case 2: + checkedonce = 1; + goto out; + default: + break; + } + + }else { + switch (check_node2(succ_node, cond, 0)) + { + case 1: + VEC_safe_push (cfg_node, heap, stack, succ_node); + break; + case 2: + if (cond->fromappearatleastonce != 0){ + checkedonce = 1; + goto out; + } + default: + break; + } + } + } } else { succ_node = node->next; - push_it = check_node (succ_node, cond); - if (push_it) - VEC_safe_push (cfg_node, heap, stack, succ_node); + if (cond->fromappearatleastonce == 0 && cond->follow == NULL) { + push_it = check_node (succ_node, cond); + if (push_it) + VEC_safe_push (cfg_node, heap, stack, succ_node); + }else if (cond->follow == NULL) { + switch (check_node1(succ_node, cond)) + { + case 1: + VEC_safe_push (cfg_node, heap, stack, succ_node); + break; + case 2: + checkedonce = 1; + goto out; + default: + break; + } + + }else { + switch (check_node2(succ_node, cond, 0)) + { + case 1: + VEC_safe_push (cfg_node, heap, stack, succ_node); + break; + case 2: + if (cond->fromappearatleastonce != 0){ + checkedonce = 1; + goto out; + } + default: + break; + } + } } } - +out: VEC_free (cfg_node, heap, stack); + return checkedonce; } /* Collect new condate instances. An instance is new if the @@ -303,7 +559,11 @@ { VEC (hole_p, heap) *stack; pattern patt = cond->from; + pattern patt1 = cond->to; + pattern patt2 = cond->function; basic_block bb; + int checkedonce = 0; + argument_holes = 0; /* Check for trivial condates. */ if (!cond->to) @@ -311,15 +571,86 @@ tree_scan (cond); return; } + + if (patt2) { + int i=0; + char *savedstr = xstrdup(patt2->format_spec); + while (savedstr[i] != ' ' && savedstr[i] != '(' && savedstr[i] != 0) + i++; + savedstr[i] = 0; + while (patt2) { + if (!strcmp(IDENTIFIER_POINTER(DECL_NAME(current_function_decl)),savedstr)) + { + break; + } + patt2 = patt2->next; + } + free(savedstr); + if (!patt2) + return; + } /* Allocate stack for collecting condate instances. */ stack = VEC_alloc (hole_p, heap, 10); patt = cond->from; + + tree_clean_typenames(); + + if (cond->types) + tree_parse_typenames(cond->types); + + patt1 = cond->to; + PP_TRACE (TRACE_CHECK, fprintf (stderr, "searching src pat %s\n", patt->format_spec)); + if (patt2){ + char * argstart; + int j = 1; + //patt_info patt; + int res = 0; + char arg[3] = {'%','_',0} ; + tree p, parms; + int i = strlen(IDENTIFIER_POINTER(DECL_NAME(current_function_decl))); + argstart = patt2->format_spec; + while (argstart[i] != '(' && argstart[i] != 0) + i++; + if (argstart[i] == 0) + goto cont; + reset_global_holes (); + i++; + while (argstart[i] == ' ') + i++; + parms = DECL_ARGUMENTS(current_function_decl); + for (p = parms; p; p = TREE_CHAIN(p)){ + if (argstart[i] != '%'){ + fprintf(stderr, "expect a hole description\n"); + goto cont; + } + i++; + arg[1] = argstart[i]; + res = tree_match (p, arg, 0); +// res = match_tree_pattinfo (p, &patt, "", 0, 0, 0); + if (!res) { + fprintf(stderr, "error matching %dth argument\n", j); + goto cont; + } + while (argstart[i] != ',' && argstart[i] != ')') + i++; + if (argstart[i] == ')'){ + argument_holes = save_global_holes(); + break; + } + i++; + while (argstart[i] == ' ') + i++; + j++; + } + } +cont: + FOR_EACH_BB (bb) { block_stmt_iterator bsi; @@ -327,8 +658,8 @@ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) { + cfg_node node = bsi_cfg_node(bsi); stmt = bsi_stmt (bsi); - PP_TRACE (TRACE_MATCH, { lazy_print_generic_expr (stderr, stmt, 0); fprintf (stderr, "= "); @@ -336,8 +667,100 @@ fprintf (stderr, "\n"); }); - if (!patt || tree_match_disj (stmt, patt, bsi_cfg_node (bsi))) - push_global_holes_if_new (stack); + if (patt && patt->format_spec && !strncmp(patt->format_spec, "entry", 5)) { + if (tree_match_disj (stmt, patt1, bsi_cfg_node (bsi))) { + if (cond->match ) { + cfg_node node1 = bsi_cfg_node(bsi)->prev; + while(node1){ + if (tree_match_disj (cfg_node_stmt(node1), cond->match, node1)) + break; + node1 = node1->prev; + } + if (node1) { + if (cond->follow) { + if ( check_node2(bsi_cfg_node(bsi), cond, 1) == 2) + push_global_holes_if_new (stack); + }else + push_global_holes_if_new (stack); + } + } else if (cond->follow) { + if ( check_node2(bsi_cfg_node(bsi), cond, 1) == 2) + push_global_holes_if_new (stack); + }else + push_global_holes_if_new (stack); + + } + + }else if (!patt || tree_match_disj (stmt, patt, bsi_cfg_node (bsi))){ + if (cond->match ) { + cfg_node node1 = bsi_cfg_node(bsi)->prev; + while(node1){ + if (tree_match_disj (cfg_node_stmt(node1), cond->match, node1)) + break; + node1 = node1->prev; + } + if (node1) + push_global_holes_if_new (stack); + } else + push_global_holes_if_new (stack); + } + else if (node->next == NULL && + TREE_CODE(stmt) == COND_EXPR) { + edge e; + edge_iterator ei; + basic_block bb; + bb = bb_for_stmt(stmt); + FOR_EACH_EDGE(e, ei, bb->succs) + { + if (e->flags&EDGE_TRUE_VALUE) { + pattern patttmp = patt; + while (patttmp) { + if (patttmp->sign == 1 && + (tree_match_prevstmt(COND_EXPR_COND (stmt), + patttmp->format_spec, node)|| + tree_match(COND_EXPR_COND(stmt), + patttmp->format_spec, node))) { + if (cond->match ) { + cfg_node node1 = bsi_cfg_node(bsi)->prev; + while(node1){ + if (tree_match_disj (cfg_node_stmt(node1), cond->match, node1)) + break; + node1 = node1->prev; + } + if (node1) + push_global_holes_if_new (stack); + } else + push_global_holes_if_new (stack); + } + patttmp = patttmp->next; + } + } + if (e->flags&EDGE_FALSE_VALUE) { + pattern patttmp = patt; + while (patttmp) { + if (patttmp->sign == -1 && + (tree_match_prevstmt(COND_EXPR_COND (stmt), + patttmp->format_spec, node)|| + tree_match(COND_EXPR_COND(stmt), + patttmp->format_spec, node))) { + if (cond->match ) { + cfg_node node1 = bsi_cfg_node(bsi)->prev; + while(node1){ + if (tree_match_disj (cfg_node_stmt(node1), cond->match, node1)) + break; + node1 = node1->prev; + } + if (node1) + push_global_holes_if_new (stack); + } else + push_global_holes_if_new (stack); + } + patttmp = patttmp->next; + } + } + + } + } } } @@ -349,11 +772,16 @@ hole_p h = VEC_pop (hole_p, stack); restore_global_holes (h); - tree_check_instance (cond); + checkedonce = tree_check_instance (cond); PP_TRACE (TRACE_CHECK, fprintf (stderr, "recounting stmts\n")); - tree_check_init (); /* clear visited flag */ + tree_check_init (); } + if (cond->fromappearatleastonce && !checkedonce) { + tree_check_warning (cond, bsi_stmt(bsi_start(ENTRY_BLOCK_PTR->next_bb)), OPT_ftree_checks_); + } + free(argument_holes); + argument_holes = 0; VEC_free (hole_p, heap, stack); } @@ -393,6 +821,7 @@ tree_check (cond); } + } condate conds[CONDMAX]; /* list of condated to check */ @@ -481,7 +910,7 @@ if (!current_check_string) { condate cond = mkcond (tree_check_string, mkpat (tree_check_string), - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0); add_condate (cond); current_check_string = tree_check_string; } Only in src/gcc: tree-check.c.back Only in src/gcc: tree-check.c~ Only in src/gcc: tree-inline.c~ diff -ur src.orig/gcc/tree-match.c src/gcc/tree-match.c --- src.orig/gcc/tree-match.c Sun Apr 15 00:14:13 2007 +++ src/gcc/tree-match.c Wed Jan 16 11:15:23 2008 @@ -45,7 +45,7 @@ hole global_holes[GLOBAL_MAX]; hole local_holes[LOCAL_MAX]; - +hole *argument_holes; /* Check whether a variable is a temporary introduced by the compiler. */ static bool @@ -270,23 +270,28 @@ return s[0]; } -static bool match_tree_pattinfo (tree, patt_info *, const char *, cfg_node); +static bool match_tree_pattinfo (tree, patt_info *, const char *, cfg_node, int i, tree tsave1); /* Worker function for match_tree_pattinfo. Matches a lazy list with a pattern. */ static bool match_chunks_pattinfo (VEC (tree_chunk, heap) *chunks, patt_info *patt, - const char *delim, cfg_node ctx_node) + const char *delim, cfg_node ctx_node, int j, tree tsave) { unsigned int i; tree_chunk chunk; + + if (j > 20) + return 0; for (i = 0; VEC_iterate (tree_chunk, chunks, i, chunk); i++) { if (chunk->t) { /* Compute delimiter for t. */ + if (chunk->t == tsave) + return 0; char next_char = (i + 1 == VEC_length (tree_chunk, chunks) ? *delim : chunk_1st_char (chunks_lookahead (chunks, i + 1))); @@ -299,7 +304,7 @@ fprintf (stderr, ", \"%s\") ", patt->format_spec); }); - if (!match_tree_pattinfo (chunk->t, patt, &next_char, ctx_node)) + if (!match_tree_pattinfo (chunk->t, patt, &next_char, ctx_node, ++j, tsave)) { PP_TRACE (TRACE_MATCH_STEPS, fprintf (stderr, "=> fail tree chunk} ")); @@ -385,10 +390,11 @@ you have a pattern with named holes. The ctx_node (if non-null) indicates the cfg_node where the tree is supposed to occur, in case some tmp vars are to be searched for from this point backwards. */ +struct entry_type *type_chain = 0; static bool match_tree_pattinfo (tree t, patt_info *patt, const char *delim, - cfg_node ctx_node) + cfg_node ctx_node, int i, tree tsave1) { tree *pt; hole *ph = NULL; @@ -422,9 +428,17 @@ { /* var hole */ /* refuse to catch a tmpvar def */ - if (is_tmp_var (t) && ctx_node && - (tree_scanf (cfg_node_stmt (ctx_node), "%t = %_", NULL, &t) - || tree_scanf (cfg_node_stmt (ctx_node), "%t = (%_)%_", + struct entry_type *entry_type; + int typesize, j, i = 0; + VEC (tree_chunk, heap) *chunks; + tree_chunk chunk; + + tree tmp; + if (is_tmp_var(t) && patt->format_spec[1] == 'T') + goto settmp; + if (is_tmp_var (t) && ctx_node && + (tree_scanf (cfg_node_stmt (ctx_node), "%t = %_", NULL, &t) + || tree_scanf (cfg_node_stmt (ctx_node), "%t = (%_)%_", NULL, &t))) { PP_TRACE (TRACE_MATCH_STEPS, @@ -432,12 +446,67 @@ "refusing to assign tmpvar def to global hole")); return 0; } - - PP_TRACE (TRACE_MATCH_STEPS, + + + PP_TRACE (TRACE_MATCH_STEPS, fprintf (stderr, "assign tree chunk to hole")); - *pt = t; - if (ph) - ph->ctx = ctx_node; +settmp: + + entry_type = type_chain; + + while (entry_type) { + if (*entry_type->holename == patt->format_spec[1]) + break; + entry_type = entry_type->next; + } + + + if (!entry_type) + goto setit; + + + if (!TREE_TYPE(t)) + goto out; + + tmp = TREE_TYPE(t); + maybe_init_pretty_print(stdout); + chunks = nolazy_dump_generic_node(tmp, 0, false); + + typesize = strlen(entry_type->typename); + for (j = 0; VEC_iterate (tree_chunk, chunks, j, chunk); j++) + { + if (chunk->s) + { + if (memcmp(entry_type->typename + i, chunk->s , + strlen(chunk->s))) { + pp_free_list(chunks); + goto out; + } + i += strlen(chunk->s); + } else { + if (chunk->c == ' ') + { + while (entry_type->typename[i] == ' ') + i++; + } else if (chunk->c != entry_type->typename[i]) + { + pp_free_list(chunks); + goto out; + }else + i++; + } + } + pp_free_list(chunks); + goto setit; + + out: + return 0; + + setit: + *pt = t; + if (ph) + ph->ctx = ctx_node; + } else { @@ -460,7 +529,9 @@ { /* Can't swallow a whole tree, must recurse on it. */ VEC (tree_chunk, heap) *chunks; - + tree tsave; + int j; + tree_chunk chunk; PP_TRACE (TRACE_MATCH_STEPS, fprintf (stderr, "check chunks vs patt")); /* Check an eventual pattern-only '(' to be skipped. */ @@ -472,16 +543,27 @@ /* On a tmpvar or a cast, there is no point to recurse directly (they cannot be in the pattern), so substitute it before. */ + tsave = 0; while ((val = substitute_tmp_var (t, ctx_node, false)) != NULL || (val = substitute_cast_expr (t)) != NULL) { PP_TRACE (TRACE_MATCH_STEPS, fprintf (stderr, "succeed subst tmp")); + tsave = t; t = val; } maybe_init_pretty_print (stdout); chunks = lazy_dump_generic_node (t, 0, false); - res = match_chunks_pattinfo (chunks, patt, delim, ctx_node); + for (j = 0; VEC_iterate (tree_chunk, chunks, j, chunk); j++) + { + if (chunk->t && chunk->t == tsave1) { + res = 0; + goto out1; + } + } + res = match_chunks_pattinfo (chunks, patt, delim, ctx_node, ++i, tsave); + +out1: pp_free_list (chunks); PP_TRACE (TRACE_MATCH_STEPS, fprintf (stderr, "%s chunks vs patt", (res? "succeed": "fail"))); @@ -538,6 +620,13 @@ global_holes[i].tree = NULL; global_holes[i].ctx = NULL; } + if (argument_holes) { + for (i=0; imatch returned %d, and fmt='%s'\n", res, patt.format_spec)); @@ -697,4 +798,180 @@ return (tree_match (t, patt->format_spec, ctx_node) || (patt->next && tree_match_disj (t, patt->next, ctx_node))); +} + +bool +tree_match_prevstmt (tree t, const char *fmt, cfg_node ctx_node) +{ + + patt_info patt; + bool res; + char *c, *c1; + char *fmt1; + hole *old_global_holes; + cfg_node node_prev; + tree prev_stmt; + fmt1 = xstrdup(fmt); + c = fmt1; + + if (!c) + return false; + + while (*c != 0) { + if (*c == ';') + break; + c++; + } + + if (*c == 0) { + free(fmt1); + return false; + } + + c1 = c; + while (*(c1 -1) == ' ') + c1--; + + *c1 = 0; + + c++; + + while (*c == ' ') + c++; + + old_global_holes = save_global_holes (); + patt.args_ptr = NULL; + patt.format_spec = c; + reset_local_holes (); + res = match_tree_pattinfo (t, &patt, "", ctx_node, 0, 0); + + /* nothing left in the pattern ? */ + if (res && (*patt.format_spec == '\0')) + ; + else + { + free(fmt1); + restore_global_holes (old_global_holes); /* unbind global holes */ + return false; + } + + node_prev = ctx_node->prev; + while (node_prev) { + patt.args_ptr = NULL; + patt.format_spec = fmt1; + prev_stmt = cfg_node_stmt(node_prev); + res = match_tree_pattinfo (prev_stmt, &patt, "", node_prev, 0, 0); + if (res && (*patt.format_spec == '\0')) + { + restore_global_holes (old_global_holes); /* unbind global holes */ + free(fmt1); + return true; + } + else if (patt.format_spec != fmt1) + { + restore_global_holes (old_global_holes); + free(fmt1); + return false; + } + node_prev = node_prev->prev; + + } + free(fmt1); + restore_global_holes (old_global_holes); /* unbind global holes */ + return false; +} + + +bool +tree_match_prevstmt_disj (tree t, pattern patt, cfg_node ctx_node) +{ + if (!patt) + return false; + + return (tree_match_prevstmt (t, patt->format_spec, ctx_node) + || (patt->next && tree_match_prevstmt_disj (t, patt->next, ctx_node))); +} + +bool tree_parse_typenames(const char * typenames) +{ + + int typesize, i; + char *typenamesave, *typenamescur; + if (!typenames || strlen(typenames) < 3) + return false; + + + typesize = strlen(typenames); + + typenamesave = typenamescur = xstrdup(typenames); + i = typesize; + + while (1) { + int j; + struct entry_type * entry_type, *tmp, *prev; + + while (typenamescur[i-1] == ' '){ + i--; + } + if (i == 1) + break; + + typenamescur[i] = 0; + + while (typenamescur [i-1] != '%') + i--; + + entry_type = xmalloc(sizeof(struct entry_type)); + entry_type->holename = xmalloc(sizeof(char)); + *entry_type->holename = typenamescur[i]; + j = i+1; + + while (typenamescur[j] == ' ') + j++; + + + while (typenamescur[j] == ' ') + j++; + + entry_type->typename = xstrdup(typenamescur + j); + + if (type_chain == 0) { + type_chain = entry_type; + entry_type->next = 0; + entry_type->prev = 0; + continue; + } + + tmp = prev = type_chain; + while (tmp) { + prev = tmp; + tmp = tmp->next; + } + + prev->next = entry_type; + entry_type->prev = prev; + entry_type->next = 0; + if (i != 1) { + i--; + while (typenamescur[i-1] == ';') + i--; + } + } + free(typenamesave); + return true; +} + +bool tree_clean_typenames(void) +{ + struct entry_type *tmp, *prev; + tmp = prev = type_chain; + while (tmp) { + prev = tmp; + tmp = tmp->next; + free(prev->holename); + free(prev->typename); + free(prev); + } + type_chain = 0; + return true; } Only in src/gcc: tree-match.c.back Only in src/gcc: tree-match.c~ diff -ur src.orig/gcc/tree-match.h src/gcc/tree-match.h --- src.orig/gcc/tree-match.h Sun Apr 15 00:14:58 2007 +++ src/gcc/tree-match.h Sun Jan 13 16:49:53 2008 @@ -61,6 +61,8 @@ struct patt_info_s *next; /* next disjunct in the pattern */ } patt_info; + + typedef patt_info *pattern; /* Atomic pattern constructor. */ @@ -137,6 +139,7 @@ property. Thus, a variable %X has the same value in different patterns. */ extern hole global_holes[GLOBAL_MAX]; +extern hole *argument_holes; extern bool is_global_hole (char c); extern hole *get_hole_named (char c); @@ -152,6 +155,19 @@ extern bool tree_scanf (tree t, const char *fmt, cfg_node ctx_node, ...); extern bool tree_match (tree t, const char *fmt, cfg_node ctx_node); extern bool tree_match_disj (tree t, pattern fmt, cfg_node ctx_node); +extern bool tree_match_prevstmt (tree t, const char *fmt, cfg_node ctx_node); +extern bool tree_match_prevstmt_disj (tree t, pattern patt, cfg_node ctx_node); + +struct entry_type { +char * holename; +char * typename; +struct entry_type *next; +struct entry_type *prev; +}; + +extern struct entry_type *type_chain; +extern bool tree_parse_typenames(const char * typenames); +extern bool tree_clean_typenames(void); /* A "condate" is a program property involving CONtrol, DATa, and other aspects such as syntactic and semantic information. For @@ -160,8 +176,13 @@ lock-unlock bugs. Thus, condates are built upon patterns, CFG and dataflow information. */ typedef struct condate_s { + int fromappearatleastonce; + char *types; char *name; /* Used to identify the condate in warning messages. */ pattern from; /* Paths start at nodes matching this pattern. */ + pattern match; + pattern function; + pattern follow; pattern to; /* Paths end at nodes matching this pattern. */ pattern avoid; /* Paths must avoid nodes matching this pattern. */ pattern avoid_then; /* ... successful conditions matching this pattern. */ @@ -172,15 +193,26 @@ /* Condate constructor. */ static inline condate mkcond (const char *name, pattern from, pattern to, pattern avoid, - pattern avoid_then, pattern avoid_else) + pattern avoid_then, pattern avoid_else, pattern match, char *types, pattern function, + pattern follow, int fromappearatleastonce) { condate cond = xmalloc (sizeof (struct condate_s)); - if (name) + if (name) cond->name = xstrdup (name); else cond->name = NULL; + if (types) { + cond->types = xstrdup(types); + free(types); + } + else + cond->types = NULL; + cond->fromappearatleastonce = fromappearatleastonce; + cond->function = function; cond->from = from; cond->to = to; + cond->follow = follow; + cond->match = match; cond->avoid = avoid; cond->avoid_then = avoid_then; cond->avoid_else = avoid_else; Only in src/gcc: tree-match.h.back Only in src/gcc: tree-match.h~ diff -ur src.orig/gcc/tree-pretty-print.c src/gcc/tree-pretty-print.c --- src.orig/gcc/tree-pretty-print.c Sun Apr 15 00:10:40 2007 +++ src/gcc/tree-pretty-print.c Thu Jan 3 11:17:58 2008 @@ -48,7 +48,7 @@ static void do_niy (pretty_printer *, tree); static void dump_vops (pretty_printer *, tree, int, int); static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int); - +static nolazy = 0; #define INDENT(SPACE) do { \ int i; for (i = 0; ibuffer->chunks = VEC_alloc (tree_chunk, heap, 10); + dump_generic_node_aux (pp, node, 0, flags, is_stmt); + nolazy = 0; + res = pp->buffer->chunks; + pp->buffer->chunks = NULL; + + return res; +} + /* Unparse the top level of a tree and dump the resulting list of tree chunks to a file */ Only in src/gcc: tree-pretty-print.c~ Only in src/gcc: tree-ssa-threadedge.c~ diff -ur src.orig/gcc/tree-vrp.c src/gcc/tree-vrp.c --- src.orig/gcc/tree-vrp.c Sun Apr 15 00:10:41 2007 +++ src/gcc/tree-vrp.c Sun Jan 6 20:12:11 2008 @@ -3649,8 +3649,7 @@ /* Traverse the strictly dominated sub-graph rooted at E->DEST to determine if any of the operands in the conditional predicate are used. */ - if (e->dest != bb) - need_assert |= find_assert_locations (e->dest); + need_assert |= find_assert_locations (e->dest); /* Register the necessary assertions for each operand in the conditional predicate. */ Only in src/gcc: tree-vrp.c~