| @@ -325,7 +325,8 @@ ST_FUNC void update_storage(Sym *sym) · 324 unmodified lines |
| 325 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | 325 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) |
| 326 | | sym->a.visibility; | 326 | | sym->a.visibility; |
| 327 | | 327 | |
| 328 | if (sym->type.t & VT_STATIC) | 328 | if ((sym->type.t & VT_STATIC) |
| | 329 | || (sym->type.t & (VT_EXTERN | VT_INLINE)) == VT_INLINE) |
| 329 | sym_bind = STB_LOCAL; | 330 | sym_bind = STB_LOCAL; |
| 330 | else if (sym->a.weak) | 331 | else if (sym->a.weak) |
| 331 | sym_bind = STB_WEAK; | 332 | sym_bind = STB_WEAK; |
| @@ -407,7 +408,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 75 unmodified lines |
| 407 | } else { | 408 | } else { |
| 408 | sym_type = STT_OBJECT; | 409 | sym_type = STT_OBJECT; |
| 409 | } | 410 | } |
| 410 | if (t & VT_STATIC) | 411 | if ((t & VT_STATIC) || (t & (VT_EXTERN | VT_INLINE)) == VT_INLINE) |
| 411 | sym_bind = STB_LOCAL; | 412 | sym_bind = STB_LOCAL; |
| 412 | else | 413 | else |
| 413 | sym_bind = STB_GLOBAL; | 414 | sym_bind = STB_GLOBAL; |
| @@ -926,7 +927,8 @@ static void merge_attr(AttributeDef *ad, AttributeDef *ad1) · 512 unmodified lines |
| 926 | /* Merge some type attributes. */ | 927 | /* Merge some type attributes. */ |
| 927 | static void patch_type(Sym *sym, CType *type) | 928 | static void patch_type(Sym *sym, CType *type) |
| 928 | { | 929 | { |
| 929 | if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) { | 930 | if ((!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) |
| | 931 | && (type->t & VT_BTYPE) != VT_FUNC) { |
| 930 | if (!(sym->type.t & VT_EXTERN)) | 932 | if (!(sym->type.t & VT_EXTERN)) |
| 931 | tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL)); | 933 | tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL)); |
| 932 | sym->type.t &= ~VT_EXTERN; | 934 | sym->type.t &= ~VT_EXTERN; |
| @@ -945,18 +947,22 @@ static void patch_type(Sym *sym, CType *type) · 12 unmodified lines |
| 945 | } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) { | 947 | } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) { |
| 946 | int static_proto = sym->type.t & VT_STATIC; | 948 | int static_proto = sym->type.t & VT_STATIC; |
| 947 | /* warn if static follows non-static function declaration */ | 949 | /* warn if static follows non-static function declaration */ |
| 948 | if ((type->t & VT_STATIC) && !static_proto && !((type->t|sym->type.t) & VT_INLINE)) | 950 | if ((type->t & VT_STATIC) && !static_proto) |
| 949 | tcc_warning("static storage ignored for redefinition of '%s'", | 951 | tcc_warning("static storage ignored for redefinition of '%s'", |
| 950 | get_tok_str(sym->v, NULL)); | 952 | get_tok_str(sym->v, NULL)); |
| 951 | | 953 | |
| | 954 | /* Force external definition if unequal inline specifier |
| | 955 | or an explicit extern one. */ |
| | 956 | if ((type->t & VT_INLINE) != (sym->type.t & VT_INLINE) |
| | 957 | || (type->t | sym->type.t) & VT_EXTERN) { |
| | 958 | type->t &= ~VT_INLINE; |
| | 959 | sym->type.t &= ~VT_INLINE; |
| | 960 | } |
| 952 | if (0 == (type->t & VT_EXTERN)) { | 961 | if (0 == (type->t & VT_EXTERN)) { |
| 953 | /* put complete type, use static from prototype */ | 962 | /* put complete type, use static from prototype */ |
| 954 | sym->type.t = (type->t & ~VT_STATIC) | static_proto; | 963 | sym->type.t = (type->t & ~VT_STATIC) | static_proto; |
| 955 | if (type->t & VT_INLINE) | | |
| 956 | sym->type.t = type->t; | | |
| 957 | sym->type.ref = type->ref; | 964 | sym->type.ref = type->ref; |
| 958 | } | 965 | } |
| 959 | | | |
| 960 | } else { | 966 | } else { |
| 961 | if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) { | 967 | if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) { |
| 962 | /* set array size if it was omitted in extern declaration */ | 968 | /* set array size if it was omitted in extern declaration */ |
| @@ -7411,17 +7417,12 @@ static void gen_inline_functions(TCCState *s) · 6448 unmodified lines |
| 7411 | for (i = 0; i < s->nb_inline_fns; ++i) { | 7417 | for (i = 0; i < s->nb_inline_fns; ++i) { |
| 7412 | fn = s->inline_fns[i]; | 7418 | fn = s->inline_fns[i]; |
| 7413 | sym = fn->sym; | 7419 | sym = fn->sym; |
| 7414 | if (sym && (sym->c || (sym->type.t&VT_INSTINL) )){ | 7420 | if (sym && (sym->c || !(sym->type.t & VT_INLINE) )){ |
| 7415 | /* the function was used: generate its code and | 7421 | /* the function was used or forced: generate its code and |
| 7416 | convert it to a normal function */ | 7422 | convert it to a normal function */ |
| 7417 | fn->sym = NULL; | 7423 | fn->sym = NULL; |
| 7418 | if (file) | 7424 | if (file) |
| 7419 | pstrcpy(file->filename, sizeof file->filename, fn->filename); | 7425 | pstrcpy(file->filename, sizeof file->filename, fn->filename); |
| 7420 | sym->type.t &= ~VT_INLINE; | | |
| 7421 | | | |
| 7422 | if (sym->type.t&VT_INSTINL) | | |
| 7423 | sym->type.t &= ~VT_STATIC; | | |
| 7424 | | | |
| 7425 | begin_macro(fn->func_str, 1); | 7426 | begin_macro(fn->func_str, 1); |
| 7426 | next(); | 7427 | next(); |
| 7427 | cur_text_section = text_section; | 7428 | cur_text_section = text_section; |
| @@ -7574,46 +7575,17 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 146 unmodified lines |
| 7574 | if (sym->type.t == VT_VOID) | 7575 | if (sym->type.t == VT_VOID) |
| 7575 | sym->type = int_type; | 7576 | sym->type = int_type; |
| 7576 | } | 7577 | } |
| 7577 | sym = type.ref; | | |
| 7578 | sym = sym_find(v); | | |
| 7579 | /* temporarily convert even extern inlines to statics */ | | |
| 7580 | if (!sym){ | | |
| 7581 | if( (type.t & VT_EXTERN) && (type.t & VT_INLINE) ){ | | |
| 7582 | type.t |= VT_INSTINL; | | |
| 7583 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC | VT_FAKESTC; | | |
| 7584 | }else if ( type.t & VT_INLINE ){ | | |
| 7585 | if(!(type.t&VT_STATIC)) type.t |= VT_FAKESTC; | | |
| 7586 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; | | |
| 7587 | } | | |
| 7588 | }else{ | | |
| 7589 | if ( !(type.t & VT_STATIC) && !(sym->type.t & VT_STATIC) ){ | | |
| 7590 | if( | | |
| 7591 | ((type.t & VT_INLINE) != (sym->type.t & VT_INLINE)) || | | |
| 7592 | ( (type.t & VT_INLINE) && (type.t & VT_EXTERN) ) | | |
| 7593 | ){ | | |
| 7594 | /* noninline decl + inline def OR inline decl + noinline def OR | | |
| 7595 | inline explicitly extern def ALL instantiate the inline */ | | |
| 7596 | type.t |= sym->type.t | VT_INSTINL; | | |
| 7597 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; | | |
| 7598 | } | | |
| 7599 | }else{ | | |
| 7600 | /*(extern on nonstatic defs following static decls are turned into true static defs)*/ | | |
| 7601 | } | | |
| 7602 | if ( sym->type.t & VT_INLINE ){ | | |
| 7603 | if(!(type.t&VT_STATIC)) type.t |= VT_FAKESTC; | | |
| 7604 | type.t |= sym->type.t; | | |
| 7605 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; | | |
| 7606 | } | | |
| 7607 | } | | |
| 7608 | | 7578 | |
| 7609 | /* put function symbol */ | 7579 | /* put function symbol */ |
| 7610 | sym = external_sym(v, &type, 0, &ad); | 7580 | sym = external_sym(v, &type, 0, &ad); |
| | 7581 | if (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF |
| | 7582 | && !(elfsym(sym)->st_other & ST_ASM_SET)) |
| | 7583 | tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL)); |
| 7611 | | 7584 | |
| 7612 | /* static inline functions are just recorded as a kind | 7585 | /* static inline functions are just recorded as a kind |
| 7613 | of macro. Their code will be emitted at the end of | 7586 | of macro. Their code will be emitted at the end of |
| 7614 | the compilation unit only if they are used */ | 7587 | the compilation unit only if they are used */ |
| 7615 | if ((sym->type.t & (VT_INLINE | VT_STATIC)) == | 7588 | if ((sym->type.t & (VT_INLINE | VT_EXTERN)) == VT_INLINE) { |
| 7616 | (VT_INLINE | VT_STATIC)) { | | |
| 7617 | struct InlineFunc *fn; | 7589 | struct InlineFunc *fn; |
| 7618 | const char *filename; | 7590 | const char *filename; |
| 7619 | | 7591 | |
| @@ -7688,16 +7660,9 @@ found: · 68 unmodified lines |
| 7688 | /* NOTE: as GCC, uninitialized global static | 7660 | /* NOTE: as GCC, uninitialized global static |
| 7689 | arrays of null size are considered as | 7661 | arrays of null size are considered as |
| 7690 | extern */ | 7662 | extern */ |
| 7691 | int t = type.t; | 7663 | if ((type.t & VT_BTYPE) != VT_FUNC) |
| 7692 | type.t |= VT_EXTERN; | 7664 | type.t |= VT_EXTERN; |
| 7693 | sym = external_sym(v, &type, r, &ad); | 7665 | sym = external_sym(v, &type, r, &ad); |
| 7694 | | | |
| 7695 | if ( (!(sym->type.t&VT_STATIC) || sym->type.t&VT_FAKESTC ) && | | |
| 7696 | ( ((sym->type.t&VT_INLINE)!=(t&VT_INLINE)) || | | |
| 7697 | ( (t&VT_INLINE) && (t&VT_EXTERN) ) ) | | |
| 7698 | ){ | | |
| 7699 | sym->type.t |= VT_INSTINL; | | |
| 7700 | } | | |
| 7701 | if (ad.alias_target) { | 7666 | if (ad.alias_target) { |
| 7702 | ElfSym *esym; | 7667 | ElfSym *esym; |
| 7703 | Sym *alias_target; | 7668 | Sym *alias_target; |
| @@ -7717,7 +7682,8 @@ found: · 13 unmodified lines |
| 7717 | r |= l; | 7682 | r |= l; |
| 7718 | if (has_init) | 7683 | if (has_init) |
| 7719 | next(); | 7684 | next(); |
| 7720 | else if (l == VT_CONST) | 7685 | else if (l == VT_CONST |
| | 7686 | && (type.t & VT_BTYPE) != VT_FUNC) |
| 7721 | /* uninitialized global variables may be overridden */ | 7687 | /* uninitialized global variables may be overridden */ |
| 7722 | type.t |= VT_EXTERN; | 7688 | type.t |= VT_EXTERN; |
| 7723 | decl_initializer_alloc(&type, &ad, r, has_init, v, l); | 7689 | decl_initializer_alloc(&type, &ad, r, has_init, v, l); |