Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package clang-extract for openSUSE:Factory checked in at 2024-07-24 15:30:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/clang-extract (Old) and /work/SRC/openSUSE:Factory/.clang-extract.new.1869 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "clang-extract" Wed Jul 24 15:30:29 2024 rev:7 rq:1189140 version:0~20240722.a998e91 Changes: -------- --- /work/SRC/openSUSE:Factory/clang-extract/clang-extract.changes 2024-07-22 17:18:50.671290940 +0200 +++ /work/SRC/openSUSE:Factory/.clang-extract.new.1869/clang-extract.changes 2024-07-25 11:47:12.717487643 +0200 @@ -1,0 +2,17 @@ +Tue Jul 23 03:52:54 UTC 2024 - mvet...@suse.com + +- Update to version 0~20240722.a998e91: + * Fix clang-extract discarding struct-partial definition in nested record + * Add (failing) testcase + * Fix clang-extract dropping complete definition of struct when a copy is necessary + * Fix struct being redefined if defined in variable type + * Extend parent RecordDecl analysis for EnumDecls + * Remove redundant leftmost decl from closure + * Avoid adding every previous decl of a global variable + * Force TagDecl as needing fulldefiniton if is a return type of a function + * Deference pointer types when searching for decomposed typedef-struct + * Analyze CleanupAttr + * Avoid adding previous declarations of typedefs into closure + * SymbolExternalizer: Check KLP_ macros only if there was externzalized syms + +------------------------------------------------------------------- Old: ---- clang-extract-0~20240721.9b2dfb6.tar.xz New: ---- clang-extract-0~20240722.a998e91.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ clang-extract.spec ++++++ --- /var/tmp/diff_new_pack.uloT4e/_old 2024-07-25 11:47:13.345512439 +0200 +++ /var/tmp/diff_new_pack.uloT4e/_new 2024-07-25 11:47:13.349512597 +0200 @@ -17,7 +17,7 @@ Name: clang-extract -Version: 0~20240721.9b2dfb6 +Version: 0~20240722.a998e91 Release: 0 Summary: A tool to extract code content from source files License: Apache-2.0 WITH LLVM-exception AND NCSA ++++++ _service ++++++ --- /var/tmp/diff_new_pack.uloT4e/_old 2024-07-25 11:47:13.389514176 +0200 +++ /var/tmp/diff_new_pack.uloT4e/_new 2024-07-25 11:47:13.393514334 +0200 @@ -2,7 +2,7 @@ <service name="tar_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/SUSE/clang-extract</param> - <param name="revision">9b2dfb68740ef30742f6afcf58e7e160958316d9</param> + <param name="revision">a998e91ea98a06179bb39f0fa6e39427ad29774b</param> <param name="versionformat">0~%cd.%h</param> <param name="changesgenerate">enable</param> <param name="changesauthor">mvet...@suse.com</param> ++++++ clang-extract-0~20240721.9b2dfb6.tar.xz -> clang-extract-0~20240722.a998e91.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/libcextract/Closure.hh new/clang-extract-0~20240722.a998e91/libcextract/Closure.hh --- old/clang-extract-0~20240721.9b2dfb6/libcextract/Closure.hh 2024-07-21 18:49:09.000000000 +0200 +++ new/clang-extract-0~20240722.a998e91/libcextract/Closure.hh 2024-07-23 01:27:55.000000000 +0200 @@ -36,9 +36,15 @@ bool Add_Decl_And_Prevs(Decl *decl); /** Add a single decl to the set. */ - void Add_Single_Decl(Decl *decl) + bool Add_Single_Decl(Decl *decl) { + /* Do not insert builtin decls. */ + if (Is_Builtin_Decl(decl)) { + return false; + } + Dependencies.insert(decl); + return true; } inline std::unordered_set<Decl *> &Get_Set(void) @@ -156,29 +162,6 @@ AnalyzedDecls.insert(decl); } - /** Check if we can get a partial declaration of `decl` rather than a full - declaration. */ - inline TagDecl *Maybe_Partial_Decl(TagDecl *decl) - { - if (decl->isCompleteDefinitionRequired()) { - /* We need the full definition of this struct, enum, or union. */ - return decl; - } else { - /* We don't need the full defintion. Hide the body for the PrettyPrint - class. */ - decl->setCompleteDefinition(false); - /* FIXME: The PrettyPrint class will attempt to write this declaration - as the user wrote, that means WITH a body. To avoid this, we set - the StartLocation to equal the End of location, which will trigger - the "clang got confused" mechanism in PrettyPrint and force it to - be output as a tree dump instead of what the user wrote. The - correct way of doing this would be update the source location to - the correct range. */ - decl->setLocStart(decl->getEndLoc()); - return decl; - } - } - enum { VISITOR_CONTINUE = true, // Return this for the AST transversal to continue; VISITOR_STOP = false, // Return this for the AST tranversal to stop completely; @@ -230,7 +213,32 @@ } } - Closure.Add_Decl_And_Prevs(to_mark); + /* Check if the return type of the function is a complete struct + definition, which in this case clang seems to ignore. */ + const clang::Type *ret_type = to_mark->getReturnType().getTypePtr(); + if (ret_type->isRecordType()) { + if (TagDecl *tag = ret_type->getAsTagDecl()) { + tag->setCompleteDefinitionRequired(true); + } + } + + Closure.Add_Single_Decl(to_mark); + + /* Also analyze the previous version of this function to make sure we are + not losing the version with body. */ + TRY_TO(AnalyzePreviousDecls(to_mark)); + + return VISITOR_CONTINUE; + } + + bool AnalyzePreviousDecls(Decl *decl) + { + Decl *prev = decl->getPreviousDecl(); + while (prev) { + TRY_TO(TraverseDecl(prev)); + Closure.Add_Single_Decl(prev); + prev = prev->getPreviousDecl(); + } return VISITOR_CONTINUE; } @@ -241,6 +249,25 @@ return VISITOR_CONTINUE; } + bool ParentRecordDeclHelper(TagDecl *decl) + { + /* In case this references a struct/union defined inside a struct (nested + struct), then we also need to analyze the parent struct. */ + RecordDecl *parent = dyn_cast<RecordDecl>(decl->getLexicalDeclContext()); + if (parent) { + /* If the parent struct is flagged as not needing a complete definition + then we need to set it to true, else the nested struct won't be + output as of only a partial definition of the parent struct is + output. */ + parent->setCompleteDefinitionRequired(true); + + /* Analyze parent struct. */ + TRY_TO(TraverseDecl(parent)); + } + + return VISITOR_CONTINUE; + } + bool VisitRecordDecl(RecordDecl *decl) { /* If this is a C++ record decl, then analyze it as such. */ @@ -259,23 +286,14 @@ typedef struct { int a; } A; */ return VisitTypedefNameDecl(typedecl); - } else { - /* In case this references a struct/union defined inside a struct (nested - struct), then we also need to analyze the parent struct. */ - RecordDecl *parent = dyn_cast<RecordDecl>(decl->getLexicalDeclContext()); - if (parent) { - /* If the parent struct is flagged as not needing a complete definition - then we need to set it to true, else the nested struct won't be - output as of only a partial definition of the parent struct is - output. */ - parent->setCompleteDefinitionRequired(true); + } - /* Analyze parent struct. */ - TRY_TO(TraverseDecl(parent)); - } + TRY_TO(ParentRecordDeclHelper(decl)); - Closure.Add_Decl_And_Prevs(Maybe_Partial_Decl(decl)); - } + Closure.Add_Single_Decl(decl); + /* Also analyze the previous version of this decl for any version of it + that is nested-declared inside another record. */ + TRY_TO(AnalyzePreviousDecls(decl)); return VISITOR_CONTINUE; } @@ -293,10 +311,15 @@ typedef enum { CONSTANT = 1 } A; */ return VisitTypedefNameDecl(typedecl); - } else { - Closure.Add_Decl_And_Prevs(decl); } + TRY_TO(ParentRecordDeclHelper(decl)); + Closure.Add_Single_Decl(decl); + + /* Also analyze the previous version of this decl for any version of it + that is nested-declared inside another record. */ + TRY_TO(AnalyzePreviousDecls(decl)); + return VISITOR_CONTINUE; } @@ -329,8 +352,9 @@ /* Not called automatically by Transverse. */ bool VisitTypedefNameDecl(TypedefNameDecl *decl) { + // FIXME: Do we need to analyze the previous decls? TRY_TO(TraverseType(decl->getUnderlyingType())); - Closure.Add_Decl_And_Prevs(decl); + Closure.Add_Single_Decl(decl); return VISITOR_CONTINUE; } @@ -343,8 +367,9 @@ bool VisitVarDecl(VarDecl *decl) { /* Avoid adding variables that are not global. */ + // FIXME: Do we need to analyze every previous decl? if (decl->hasGlobalStorage()) { - Closure.Add_Decl_And_Prevs(decl); + Closure.Add_Single_Decl(decl); } return VISITOR_CONTINUE; @@ -460,6 +485,27 @@ return VISITOR_CONTINUE; } + bool VisitUnaryOperator(const UnaryOperator *expr) + { + /* Fix cases where a copy of a struct is necessary but + * CompleteDefinitionRequired is somehow set to false by clang itself. + * see small/record-9.c for an example. + */ + const clang::Type *type = expr->getType().getTypePtr(); + if (TagDecl *tag = type->getAsTagDecl()) { + tag->setCompleteDefinitionRequired(true); + } + + return VISITOR_CONTINUE; + } + + /* --------- Attributes ----------- */ + bool VisitCleanupAttr(const CleanupAttr *attr) + { + TRY_TO(TraverseDecl(attr->getFunctionDecl())); + return VISITOR_CONTINUE; + } + /* -------- Types ----------------- */ bool VisitTagType(const TagType *type) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/libcextract/FunctionDepsFinder.cpp new/clang-extract-0~20240722.a998e91/libcextract/FunctionDepsFinder.cpp --- old/clang-extract-0~20240721.9b2dfb6/libcextract/FunctionDepsFinder.cpp 2024-07-21 18:49:09.000000000 +0200 +++ new/clang-extract-0~20240722.a998e91/libcextract/FunctionDepsFinder.cpp 2024-07-23 01:27:55.000000000 +0200 @@ -95,6 +95,20 @@ const clang::Type *type = decl->getTypeForDecl(); if (type) { + /* We must be careful with pointers, the user can define things like: + * + * typedef struct _fakestr { + * struct _fakestr *pNext; + * int type; + * } FAKE, *PFAKE; + * + * which in this case PFAKE is a pointer and we need to deference it + * to reach _fakestr. + */ + while (type->isPointerType()) { + type = type->getPointeeOrArrayElementType(); + } + TagDecl *typedecl = type->getAsTagDecl(); if (typedecl && closure.Is_Decl_Marked(typedecl)) { @@ -188,9 +202,10 @@ // FIXME: use interval tree ASTUnit::top_level_iterator it; - TypedefDecl *prev = nullptr; + Decl *prev = nullptr; for (it = AST->top_level_begin(); it != AST->top_level_end(); ++it) { - if (TypedefDecl *decl = dyn_cast<TypedefDecl>(*it)) { + Decl *decl = *it; + if (isa<TypedefDecl>(decl) || isa<VarDecl>(decl) || isa<TagDecl>(decl)) { if (!closure.Is_Decl_Marked(decl)) continue; @@ -224,8 +239,14 @@ * Which then breaks the one-definition-rule. In such cases, remove the * previous declaration in the same code range, since the later will * contain both definitions either way. + * + * Also be careful to make sure those declarations will be print as + * based on the source text and not in AST dump. In the later case + * we don't want to remove it. */ - if (PrettyPrint::Contains_From_LineCol(decl->getSourceRange(), + if (PrettyPrint::Get_Source_Text(decl->getSourceRange()) != "" && + PrettyPrint::Get_Source_Text(prev->getSourceRange()) != "" && + PrettyPrint::Contains_From_LineCol(decl->getSourceRange(), prev->getSourceRange())) { /* * If the prev and the current decl have the same start LoC, but diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/libcextract/Passes.cpp new/clang-extract-0~20240722.a998e91/libcextract/Passes.cpp --- old/clang-extract-0~20240721.9b2dfb6/libcextract/Passes.cpp 2024-07-21 18:49:09.000000000 +0200 +++ new/clang-extract-0~20240722.a998e91/libcextract/Passes.cpp 2024-07-23 01:27:55.000000000 +0200 @@ -459,7 +459,7 @@ ClangCompat_None, ctx->OFS); PrettyPrint::Set_AST(ctx->AST.get()); - if (ctx->Ibt && ctx->AST) { + if (ctx->Ibt && ctx->AST && externalizer.Has_Externalizations()) { /* Do a sanity check on IBT macros. Some kernel branches can't use it, so do a check here for sanity reasons. */ Preprocessor &pp = ctx->AST->getPreprocessor(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/libcextract/PrettyPrint.cpp new/clang-extract-0~20240722.a998e91/libcextract/PrettyPrint.cpp --- old/clang-extract-0~20240721.9b2dfb6/libcextract/PrettyPrint.cpp 2024-07-21 18:49:09.000000000 +0200 +++ new/clang-extract-0~20240722.a998e91/libcextract/PrettyPrint.cpp 2024-07-23 01:27:55.000000000 +0200 @@ -47,8 +47,32 @@ because it contains declared constants. */ } else { /* Structs and prototypes */ + + /** Check if we can get a partial declaration of `decl` rather than a full + declaration. */ + bool full_def_removed = false; + if (t && t->isCompleteDefinitionRequired() == false) { + /* We don't need the full defintion. Hide the body for Print_Decl_Raw. */ + t->setCompleteDefinition(false); + + /* FIXME: The Print_Decl_Raw class will attempt to write this declaration + as the user wrote, that means WITH a body. To avoid this, we set + the StartLocation to equal the End of location, which will trigger + the "clang got confused" mechanism in PrettyPrint and force it to + be output as a tree dump instead of what the user wrote. The + correct way of doing this would be update the source location to + the correct range. */ + t->setLocStart(t->getEndLoc()); + + full_def_removed = true; + } + Print_Decl_Raw(decl); - Out << ";\n\n"; + Out << ';'; + if (full_def_removed) { + Out << "/* Full definition was removed. */"; + } + Out << "\n\n"; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/libcextract/SymbolExternalizer.hh new/clang-extract-0~20240722.a998e91/libcextract/SymbolExternalizer.hh --- old/clang-extract-0~20240721.9b2dfb6/libcextract/SymbolExternalizer.hh 2024-07-21 18:49:09.000000000 +0200 +++ new/clang-extract-0~20240722.a998e91/libcextract/SymbolExternalizer.hh 2024-07-23 01:27:55.000000000 +0200 @@ -340,6 +340,17 @@ return Log; } + /** Returns true if there was at least one externalized symbol */ + inline bool Has_Externalizations(void) + { + for (auto const& [key, val] : SymbolsMap) { + if (val.ExtType == ExternalizationType::STRONG) + return true; + } + + return false; + } + /** Dump the SymbolsMap structure into stdout for debugging purposes. */ void Dump_SymbolsMap(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/attr-12.c new/clang-extract-0~20240722.a998e91/testsuite/small/attr-12.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/attr-12.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/attr-12.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,16 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +typedef struct _GFile GFile; +typedef GFile *GFile_autoptr; +static __attribute__((__unused__)) inline void +glib_autoptr_cleanup_GFile(GFile **_ptr) { + return; +} + +void f() { + GFile** ptr; + __attribute__((cleanup(glib_autoptr_cleanup_GFile))) GFile_autoptr + socket_dir = ((void *)0); +} + +/* { dg-final { scan-tree-dump "glib_autoptr_cleanup_GFile\(GFile \*\*_ptr\)" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-4.c new/clang-extract-0~20240722.a998e91/testsuite/small/closure-4.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-4.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/closure-4.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,16 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +void b() { +} + +void a() { + b(); +} + +void f() { + extern void a(); + a(); +} + +/* { dg-final { scan-tree-dump "void b\(\) {" } } */ +/* { dg-final { scan-tree-dump "void a\(\) {" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-5.c new/clang-extract-0~20240722.a998e91/testsuite/small/closure-5.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-5.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/closure-5.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,27 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=ext2fs_casefold_cmp -DCE_NO_EXTERNALIZATION" }*/ + +typedef long unsigned int size_t; + +struct struct_ext2_filsys { + const struct ext2fs_nls_table *encoding; +}; + +extern const struct ext2fs_nls_table *ext2fs_load_nls_table(int encoding); +extern int ext2fs_casefold_cmp(const struct ext2fs_nls_table *table, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2); + +struct ext2fs_nls_table { + int version; + const struct ext2fs_nls_ops *ops; +}; + +int ext2fs_casefold_cmp(const struct ext2fs_nls_table *table, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2) +{ + (void) *table; + return 0; +} + +/* { dg-final { scan-tree-dump "struct struct_ext2_filsys {\n *const struct ext2fs_nls_table \*encoding;\n};" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-6.c new/clang-extract-0~20240722.a998e91/testsuite/small/closure-6.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/closure-6.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/closure-6.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,29 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=ext2fs_casefold_cmp -DCE_NO_EXTERNALIZATION" }*/ + +typedef long unsigned int size_t; + +struct ext2fs_nls_table; + +struct struct_ext2_filsys { + const struct ext2fs_nls_table *encoding; +}; + +extern const struct ext2fs_nls_table *ext2fs_load_nls_table(int encoding); +extern int ext2fs_casefold_cmp(const struct ext2fs_nls_table *table, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2); + +struct ext2fs_nls_table { + int version; + const struct ext2fs_nls_ops *ops; +}; + +int ext2fs_casefold_cmp(const struct ext2fs_nls_table *table, + const unsigned char *str1, size_t len1, + const unsigned char *str2, size_t len2) +{ + (void) *table; + return 0; +} + +/* { dg-final { scan-tree-dump-not "struct struct_ext2_filsys {" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/enum-10.c new/clang-extract-0~20240722.a998e91/testsuite/small/enum-10.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/enum-10.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/enum-10.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,50 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ +/* { dg-xfail } */ + +enum { + NB_POSNR = 0, + NB_LENGTH, + NB_RESPOS, + NB_TRKLEN, + NB_SSNR, + NB_CURSS, + NB_SSPOS, + NB_CHANS, + NB_MIXG, + NB_SPEEDMULT, + NB_DRUMPADMODE, + NB_END +}; +enum { + INB_INS = 0, + INB_VOL, + INB_WAVELEN, + INB_ATTACK, + INB_AVOL, + INB_DECAY, + INB_DVOL, + INB_SUSTAIN, + INB_RELEASE, + INB_RVOL, + INB_VIBDELAY, + INB_VIBDEPTH, + INB_VIBSPEED, + INB_SQRLOWER, + INB_SQRUPPER, + INB_SQRSPEED, + INB_FLTLOWER, + INB_FLTUPPER, + INB_FLTSPEED, + INB_PERFSPEED, + INB_PERFLEN, + INB_HARDCUT, + INB_RELCUT, + INB_END +}; + +int a[NB_END], b[INB_END]; +void f() { int d = b[2]; } + +/* { dg-final { scan-tree-dump "b[INB_END];" } } */ +/* { dg-final { scan-tree-dump "NB_END" } } */ +/* { dg-final { scan-tree-dump "INB_END" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-2.c new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-2.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-2.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-2.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,16 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +typedef struct pglist_data { + int nr_zones; +} pg_data_t; +extern pg_data_t *node_data[]; + +extern struct pglist_data *node_data[]; + +void f() { + struct pglist_data *a; + node_data[1] = a; +} + +/* { dg-final { scan-tree-dump "struct pglist_data;" } } */ +/* { dg-final { scan-tree-dump "extern struct pglist_data \*node_data\[\];" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-3.c new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-3.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-3.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-3.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,25 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=g,f -DCE_NO_EXTERNALIZATION" }*/ + +typedef struct pglist_data { + int nr_zones; +} pg_data_t; + +extern pg_data_t *node_data[]; + +void g(void) +{ + struct pglist_data *a = (void *) 0; + node_data[0] = a; +} + +extern struct pglist_data *node_data[]; + +void f() +{ + struct pglist_data *a; + node_data[1] = a; +} + +/* { dg-final { scan-tree-dump "typedef struct pglist_data {" } } */ +/* { dg-final { scan-tree-dump "extern pg_data_t \*node_data\[\];" } } */ +/* { dg-final { scan-tree-dump "extern struct pglist_data \*node_data\[\];" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-4.c new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-4.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/globalvars-4.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/globalvars-4.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,13 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +extern double pow (double __x, double __y) __attribute__ ((__nothrow__ )); +extern double __pow (double __x, double __y) __attribute__ ((__nothrow__ )); + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +void f() { + float z = (float) pow(stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; +} + +/* { dg-final { scan-tree-dump "static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;" } } */ +/* { dg-final { scan-tree-dump-not "static float stbi__h2l_gamma_i=1.0f/2.2f;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-10.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-10.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-10.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-10.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,22 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; + +void f(struct tm **a, struct tm **b) +{ + *a = *b; +} + +/* { dg-final { scan-tree-dump "struct tm;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-11.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-11.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-11.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-11.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,13 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct files { + const char *fname; + int mode; +} *files; + +void f(void) +{ + int a = files[0].mode; +} + +/* { dg-final { scan-tree-dump "struct files {" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-6.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-6.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-6.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-6.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,17 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + + +struct NCDObject_s { + int data_int; + void *data_ptr; + void *method_user; +}; + +typedef struct NCDObject_s NCDObject; + +NCDObject NCDObject_build(); +void f () { + NCDObject_build(); +} + +/* { dg-final { scan-tree-dump "struct NCDObject_s {\n *int data_int;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-7.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-7.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-7.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-7.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,13 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct NCDObject_s { + int data_int; + void *data_ptr; + void *method_user; +}; +struct NCDObject_s NCDObject_build(); +void f () { + NCDObject_build(); +} + +/* { dg-final { scan-tree-dump "struct NCDObject_s {\n *int data_int;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-8.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-8.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-8.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-8.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,12 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +static struct block { + unsigned int secnr; +} *blockhead; + +void f() { + unsigned int a = blockhead->secnr; +} + +/* { dg-final { scan-tree-dump "static struct block {\n *unsigned int secnr;\n} *\*blockhead;" } } */ +/* { dg-final { scan-tree-dump-not "^struct block {" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-9.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-9.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-9.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-9.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,22 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; + +void f(struct tm *a, struct tm *b) +{ + *a = *b; +} + +/* { dg-final { scan-tree-dump "struct tm {" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-nested-4.c new/clang-extract-0~20240722.a998e91/testsuite/small/record-nested-4.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/record-nested-4.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/record-nested-4.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,33 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +extern int strncasecmp (const char *__s1, const char *__s2, unsigned long __n) + __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); + +extern unsigned long strlen (const char *__s) + __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); + +struct config { + enum sched_prio { + SCHED_ERR = -1, + SCHED_HIGH, + SCHED_DEFAULT, + SCHED_LOW + } prio; + unsigned int verbose; +}; + +/** clang-extract: from source.c:1511:1 */ +enum sched_prio f(const char *str) +{ + if (strncasecmp("high", str, strlen(str)) == 0) + return SCHED_HIGH; + else if (strncasecmp("default", str, strlen(str)) == 0) + return SCHED_DEFAULT; + else if (strncasecmp("low", str, strlen(str)) == 0) + return SCHED_LOW; + else + return SCHED_ERR; +} + +/* { dg-final { scan-tree-dump "struct config *{" } } */ +/* { dg-final { scan-tree-dump " *enum sched_prio *{" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-11.c new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-11.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-11.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-11.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,11 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +typedef __builtin_va_list __gnuc_va_list; +typedef __gnuc_va_list va_list; +typedef __builtin_va_list va_list; + +void f() { + va_list args; +} + +/* { dg-final { scan-tree-dump "typedef __builtin_va_list va_list;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-12.c new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-12.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-12.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-12.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,24 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct AA { + int a; +}; + +typedef struct AA _A; +typedef struct AA _B; + +typedef _A A; +typedef _B A; + +int f() { + A b; + return b.a; +} + + +/* { dg-final { scan-tree-dump "struct AA {" } } */ +/* { dg-final { scan-tree-dump "typedef struct AA _B;" } } */ +/* { dg-final { scan-tree-dump "typedef _B A;" } } */ + +/* { dg-final { scan-tree-dump-not "typedef _A A;" } } */ +/* { dg-final { scan-tree-dump-not "typedef struct AA _A;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-13.c new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-13.c --- old/clang-extract-0~20240721.9b2dfb6/testsuite/small/typedef-13.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20240722.a998e91/testsuite/small/typedef-13.c 2024-07-23 01:27:55.000000000 +0200 @@ -0,0 +1,19 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +typedef struct _fakestr { + struct _fakestr *pNext; + int type; +} FAKE, *PFAKE; + +typedef struct { + PFAKE pFakeThings; +} DPYINFO, *PDPYINFO; + +int f(PDPYINFO pDpyInfo) { + return pDpyInfo->pFakeThings->pNext->type; +} + +/* { dg-final { scan-tree-dump "typedef struct _fakestr {\n *struct _fakestr \*pNext;\n *int type;\n} *FAKE, \*PFAKE;" } } */ +/* { dg-final { scan-tree-dump "typedef struct {\n *PFAKE pFakeThings;\n} DPYINFO, \*PDPYINFO;" } } */ + +/* { dg-final { scan-tree-dump-not "struct _fakestr {\n *struct _fakestr \*pNext;\n *int type;\n};" } } */