Print this page
11972 resync smatch


  15  * all copies or substantial portions of the Software.
  16  *
  17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23  * THE SOFTWARE.
  24  */
  25 
  26 #include <stdlib.h>
  27 #include <stdio.h>
  28 
  29 #include "lib.h"
  30 #include "allocate.h"
  31 #include "token.h"
  32 #include "parse.h"
  33 #include "symbol.h"
  34 #include "expression.h"

  35 


  36 static struct expression * dup_expression(struct expression *expr)
  37 {
  38         struct expression *dup = alloc_expression(expr->pos, expr->type);
  39         *dup = *expr;
  40         return dup;
  41 }
  42 
  43 static struct statement * dup_statement(struct statement *stmt)
  44 {
  45         struct statement *dup = alloc_statement(stmt->pos, stmt->type);
  46         *dup = *stmt;
  47         return dup;
  48 }
  49 
  50 static struct symbol *copy_symbol(struct position pos, struct symbol *sym)
  51 {
  52         if (!sym)
  53                 return sym;
  54         if (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN | MOD_TOPLEVEL | MOD_INLINE))
  55                 return sym;


 161                         *expr->cast_type = *sym;
 162                         break;
 163                 }
 164         case EXPR_FORCE_CAST:
 165         case EXPR_IMPLIED_CAST:
 166         case EXPR_SIZEOF: 
 167         case EXPR_PTRSIZEOF:
 168         case EXPR_ALIGNOF: {
 169                 struct expression *cast = copy_expression(expr->cast_expression);
 170                 if (cast == expr->cast_expression)
 171                         break;
 172                 expr = dup_expression(expr);
 173                 expr->cast_expression = cast;
 174                 break;
 175         }
 176 
 177         /* Conditional expression */
 178         case EXPR_SELECT:
 179         case EXPR_CONDITIONAL: {
 180                 struct expression *cond = copy_expression(expr->conditional);
 181                 struct expression *true = copy_expression(expr->cond_true);
 182                 struct expression *false = copy_expression(expr->cond_false);
 183                 if (cond == expr->conditional && true == expr->cond_true && false == expr->cond_false)
 184                         break;
 185                 expr = dup_expression(expr);
 186                 expr->conditional = cond;
 187                 expr->cond_true = true;
 188                 expr->cond_false = false;
 189                 break;
 190         }
 191 
 192         /* Statement expression */
 193         case EXPR_STATEMENT: {
 194                 struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND);
 195                 copy_statement(expr->statement, stmt);
 196                 expr = dup_expression(expr);
 197                 expr->statement = stmt;
 198                 break;
 199         }
 200 
 201         /* Call expression */
 202         case EXPR_CALL: {
 203                 struct expression *fn = copy_expression(expr->fn);
 204                 struct expression_list *list = expr->args;
 205                 struct expression *arg;
 206 
 207                 expr = dup_expression(expr);
 208                 expr->fn = fn;


 254                 expr->init_expr = val;
 255                 break;
 256         }
 257         case EXPR_OFFSETOF: {
 258                 struct expression *val = copy_expression(expr->down);
 259                 if (expr->op == '.') {
 260                         if (expr->down != val) {
 261                                 expr = dup_expression(expr);
 262                                 expr->down = val;
 263                         }
 264                 } else {
 265                         struct expression *idx = copy_expression(expr->index);
 266                         if (expr->down != val || expr->index != idx) {
 267                                 expr = dup_expression(expr);
 268                                 expr->down = val;
 269                                 expr->index = idx;
 270                         }
 271                 }
 272                 break;
 273         }






 274         default:
 275                 warning(expr->pos, "trying to copy expression type %d", expr->type);
 276         }
 277         return expr;
 278 }
 279 
 280 static struct expression_list *copy_asm_constraints(struct expression_list *in)
 281 {
 282         struct expression_list *out = NULL;
 283         struct expression *expr;
 284         int state = 0;
 285 
 286         FOR_EACH_PTR(in, expr) {
 287                 switch (state) {
 288                 case 0: /* identifier */
 289                 case 1: /* constraint */
 290                         state++;
 291                         add_expression(&out, expr);
 292                         continue;
 293                 case 2: /* expression */
 294                         state = 0;
 295                         add_expression(&out, copy_expression(expr));
 296                         continue;
 297                 }
 298         } END_FOR_EACH_PTR(expr);
 299         return out;
 300 }
 301 
 302 static void set_replace(struct symbol *old, struct symbol *new)
 303 {
 304         new->replace = old;
 305         old->replace = new;
 306 }
 307 
 308 static void unset_replace(struct symbol *sym)
 309 {
 310         struct symbol *r = sym->replace;
 311         if (!r) {
 312                 warning(sym->pos, "symbol '%s' not replaced?", show_ident(sym->ident));
 313                 return;
 314         }
 315         r->replace = NULL;
 316         sym->replace = NULL;
 317 }


 352                 stmt = dup_statement(stmt);
 353                 stmt->expression = expr;
 354                 break;
 355         }
 356         case STMT_RANGE: {
 357                 struct expression *expr = copy_expression(stmt->range_expression);
 358                 if (expr == stmt->expression)
 359                         break;
 360                 stmt = dup_statement(stmt);
 361                 stmt->range_expression = expr;
 362                 break;
 363         }
 364         case STMT_COMPOUND: {
 365                 struct statement *new = alloc_statement(stmt->pos, STMT_COMPOUND);
 366                 copy_statement(stmt, new);
 367                 stmt = new;
 368                 break;
 369         }
 370         case STMT_IF: {
 371                 struct expression *cond = stmt->if_conditional;
 372                 struct statement *true = stmt->if_true;
 373                 struct statement *false = stmt->if_false;
 374 
 375                 cond = copy_expression(cond);
 376                 true = copy_one_statement(true);
 377                 false = copy_one_statement(false);
 378                 if (stmt->if_conditional == cond &&
 379                     stmt->if_true == true &&
 380                     stmt->if_false == false)
 381                         break;
 382                 stmt = dup_statement(stmt);
 383                 stmt->if_conditional = cond;
 384                 stmt->if_true = true;
 385                 stmt->if_false = false;
 386                 break;
 387         }
 388         case STMT_RETURN: {
 389                 struct expression *retval = copy_expression(stmt->ret_value);
 390                 struct symbol *sym = copy_symbol(stmt->pos, stmt->ret_target);
 391 
 392                 stmt = dup_statement(stmt);
 393                 stmt->ret_value = retval;
 394                 stmt->ret_target = sym;
 395                 break;
 396         }
 397         case STMT_CASE: {
 398                 stmt = dup_statement(stmt);
 399                 stmt->case_label = copy_symbol(stmt->pos, stmt->case_label);
 400                 stmt->case_label->stmt = stmt;
 401                 stmt->case_expression = copy_expression(stmt->case_expression);
 402                 stmt->case_to = copy_expression(stmt->case_to);
 403                 stmt->case_statement = copy_one_statement(stmt->case_statement);
 404                 break;
 405         }


 451                 stmt->asm_outputs = copy_asm_constraints(stmt->asm_outputs);
 452                 /* no need to dup "clobbers", since they are all constant strings */
 453                 break;
 454         }
 455         default:
 456                 warning(stmt->pos, "trying to copy statement type %d", stmt->type);
 457                 break;
 458         }
 459         return stmt;
 460 }
 461 
 462 /*
 463  * Copy a statement tree from 'src' to 'dst', where both
 464  * source and destination are of type STMT_COMPOUND.
 465  *
 466  * We do this for the tree-level inliner.
 467  *
 468  * This doesn't do the symbol replacement right: it's not
 469  * re-entrant.
 470  */
 471 void copy_statement(struct statement *src, struct statement *dst)
 472 {
 473         struct statement *stmt;
 474 
 475         FOR_EACH_PTR(src->stmts, stmt) {
 476                 add_statement(&dst->stmts, copy_one_statement(stmt));
 477         } END_FOR_EACH_PTR(stmt);
 478         dst->args = copy_one_statement(src->args);
 479         dst->ret = copy_symbol(src->pos, src->ret);
 480         dst->inline_fn = src->inline_fn;
 481 }
 482 
 483 static struct symbol *create_copy_symbol(struct symbol *orig)
 484 {
 485         struct symbol *sym = orig;
 486         if (orig) {
 487                 sym = alloc_symbol(orig->pos, orig->type);
 488                 *sym = *orig;
 489                 sym->bb_target = NULL;
 490                 sym->pseudo = NULL;
 491                 set_replace(orig, sym);




  15  * all copies or substantial portions of the Software.
  16  *
  17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23  * THE SOFTWARE.
  24  */
  25 
  26 #include <stdlib.h>
  27 #include <stdio.h>
  28 
  29 #include "lib.h"
  30 #include "allocate.h"
  31 #include "token.h"
  32 #include "parse.h"
  33 #include "symbol.h"
  34 #include "expression.h"
  35 #include "evaluate.h"
  36 
  37 static void copy_statement(struct statement *src, struct statement *dst);
  38 
  39 static struct expression * dup_expression(struct expression *expr)
  40 {
  41         struct expression *dup = alloc_expression(expr->pos, expr->type);
  42         *dup = *expr;
  43         return dup;
  44 }
  45 
  46 static struct statement * dup_statement(struct statement *stmt)
  47 {
  48         struct statement *dup = alloc_statement(stmt->pos, stmt->type);
  49         *dup = *stmt;
  50         return dup;
  51 }
  52 
  53 static struct symbol *copy_symbol(struct position pos, struct symbol *sym)
  54 {
  55         if (!sym)
  56                 return sym;
  57         if (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN | MOD_TOPLEVEL | MOD_INLINE))
  58                 return sym;


 164                         *expr->cast_type = *sym;
 165                         break;
 166                 }
 167         case EXPR_FORCE_CAST:
 168         case EXPR_IMPLIED_CAST:
 169         case EXPR_SIZEOF: 
 170         case EXPR_PTRSIZEOF:
 171         case EXPR_ALIGNOF: {
 172                 struct expression *cast = copy_expression(expr->cast_expression);
 173                 if (cast == expr->cast_expression)
 174                         break;
 175                 expr = dup_expression(expr);
 176                 expr->cast_expression = cast;
 177                 break;
 178         }
 179 
 180         /* Conditional expression */
 181         case EXPR_SELECT:
 182         case EXPR_CONDITIONAL: {
 183                 struct expression *cond = copy_expression(expr->conditional);
 184                 struct expression *valt = copy_expression(expr->cond_true);
 185                 struct expression *valf = copy_expression(expr->cond_false);
 186                 if (cond == expr->conditional && valt == expr->cond_true && valf == expr->cond_false)
 187                         break;
 188                 expr = dup_expression(expr);
 189                 expr->conditional = cond;
 190                 expr->cond_true = valt;
 191                 expr->cond_false = valf;
 192                 break;
 193         }
 194 
 195         /* Statement expression */
 196         case EXPR_STATEMENT: {
 197                 struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND);
 198                 copy_statement(expr->statement, stmt);
 199                 expr = dup_expression(expr);
 200                 expr->statement = stmt;
 201                 break;
 202         }
 203 
 204         /* Call expression */
 205         case EXPR_CALL: {
 206                 struct expression *fn = copy_expression(expr->fn);
 207                 struct expression_list *list = expr->args;
 208                 struct expression *arg;
 209 
 210                 expr = dup_expression(expr);
 211                 expr->fn = fn;


 257                 expr->init_expr = val;
 258                 break;
 259         }
 260         case EXPR_OFFSETOF: {
 261                 struct expression *val = copy_expression(expr->down);
 262                 if (expr->op == '.') {
 263                         if (expr->down != val) {
 264                                 expr = dup_expression(expr);
 265                                 expr->down = val;
 266                         }
 267                 } else {
 268                         struct expression *idx = copy_expression(expr->index);
 269                         if (expr->down != val || expr->index != idx) {
 270                                 expr = dup_expression(expr);
 271                                 expr->down = val;
 272                                 expr->index = idx;
 273                         }
 274                 }
 275                 break;
 276         }
 277         case EXPR_ASM_OPERAND: {
 278                 expr = dup_expression(expr);
 279                 expr->constraint = copy_expression(expr->constraint);
 280                 expr->expr = copy_expression(expr->expr);
 281                 break;
 282         }
 283         default:
 284                 warning(expr->pos, "trying to copy expression type %d", expr->type);
 285         }
 286         return expr;
 287 }
 288 
 289 static struct expression_list *copy_asm_constraints(struct expression_list *in)
 290 {
 291         struct expression_list *out = NULL;
 292         struct expression *expr;

 293 
 294         FOR_EACH_PTR(in, expr) {








 295                 add_expression(&out, copy_expression(expr));


 296         } END_FOR_EACH_PTR(expr);
 297         return out;
 298 }
 299 
 300 static void set_replace(struct symbol *old, struct symbol *new)
 301 {
 302         new->replace = old;
 303         old->replace = new;
 304 }
 305 
 306 static void unset_replace(struct symbol *sym)
 307 {
 308         struct symbol *r = sym->replace;
 309         if (!r) {
 310                 warning(sym->pos, "symbol '%s' not replaced?", show_ident(sym->ident));
 311                 return;
 312         }
 313         r->replace = NULL;
 314         sym->replace = NULL;
 315 }


 350                 stmt = dup_statement(stmt);
 351                 stmt->expression = expr;
 352                 break;
 353         }
 354         case STMT_RANGE: {
 355                 struct expression *expr = copy_expression(stmt->range_expression);
 356                 if (expr == stmt->expression)
 357                         break;
 358                 stmt = dup_statement(stmt);
 359                 stmt->range_expression = expr;
 360                 break;
 361         }
 362         case STMT_COMPOUND: {
 363                 struct statement *new = alloc_statement(stmt->pos, STMT_COMPOUND);
 364                 copy_statement(stmt, new);
 365                 stmt = new;
 366                 break;
 367         }
 368         case STMT_IF: {
 369                 struct expression *cond = stmt->if_conditional;
 370                 struct statement *valt = stmt->if_true;
 371                 struct statement *valf = stmt->if_false;
 372 
 373                 cond = copy_expression(cond);
 374                 valt = copy_one_statement(valt);
 375                 valf = copy_one_statement(valf);
 376                 if (stmt->if_conditional == cond &&
 377                     stmt->if_true == valt &&
 378                     stmt->if_false == valf)
 379                         break;
 380                 stmt = dup_statement(stmt);
 381                 stmt->if_conditional = cond;
 382                 stmt->if_true = valt;
 383                 stmt->if_false = valf;
 384                 break;
 385         }
 386         case STMT_RETURN: {
 387                 struct expression *retval = copy_expression(stmt->ret_value);
 388                 struct symbol *sym = copy_symbol(stmt->pos, stmt->ret_target);
 389 
 390                 stmt = dup_statement(stmt);
 391                 stmt->ret_value = retval;
 392                 stmt->ret_target = sym;
 393                 break;
 394         }
 395         case STMT_CASE: {
 396                 stmt = dup_statement(stmt);
 397                 stmt->case_label = copy_symbol(stmt->pos, stmt->case_label);
 398                 stmt->case_label->stmt = stmt;
 399                 stmt->case_expression = copy_expression(stmt->case_expression);
 400                 stmt->case_to = copy_expression(stmt->case_to);
 401                 stmt->case_statement = copy_one_statement(stmt->case_statement);
 402                 break;
 403         }


 449                 stmt->asm_outputs = copy_asm_constraints(stmt->asm_outputs);
 450                 /* no need to dup "clobbers", since they are all constant strings */
 451                 break;
 452         }
 453         default:
 454                 warning(stmt->pos, "trying to copy statement type %d", stmt->type);
 455                 break;
 456         }
 457         return stmt;
 458 }
 459 
 460 /*
 461  * Copy a statement tree from 'src' to 'dst', where both
 462  * source and destination are of type STMT_COMPOUND.
 463  *
 464  * We do this for the tree-level inliner.
 465  *
 466  * This doesn't do the symbol replacement right: it's not
 467  * re-entrant.
 468  */
 469 static void copy_statement(struct statement *src, struct statement *dst)
 470 {
 471         struct statement *stmt;
 472 
 473         FOR_EACH_PTR(src->stmts, stmt) {
 474                 add_statement(&dst->stmts, copy_one_statement(stmt));
 475         } END_FOR_EACH_PTR(stmt);
 476         dst->args = copy_one_statement(src->args);
 477         dst->ret = copy_symbol(src->pos, src->ret);
 478         dst->inline_fn = src->inline_fn;
 479 }
 480 
 481 static struct symbol *create_copy_symbol(struct symbol *orig)
 482 {
 483         struct symbol *sym = orig;
 484         if (orig) {
 485                 sym = alloc_symbol(orig->pos, orig->type);
 486                 *sym = *orig;
 487                 sym->bb_target = NULL;
 488                 sym->pseudo = NULL;
 489                 set_replace(orig, sym);