Outils pour utilisateurs

Outils du site


prog:clang

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
prog:clang [2023/05/10 09:58] – Séparation de clang-tidy rootprog:clang [2024/05/21 11:04] (Version actuelle) – [Compilation] : ne pas compiler les utilitaires root
Ligne 5: Ligne 5:
 =====Installation===== =====Installation=====
  
 +====Compilation====
 +
 +Pour faire une compilation plus rapide, ajouter :
 +
 +Dossier source : ''llvm-project\llvm''.
 +
 +''-DLLVM_TARGETS_TO_BUILD=X86'' pour compiler pour x86 et x64.
 +
 +''-DCMAKE_INSTALL_PREFIX=install'' car ce dossier a besoin d'être accessible en écriture pendant la compilation.
 +
 +''%%-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra"%%''. ''clang-tools-extra'' est nécessaire pour ''ClangAST''.
 +
 +''%%-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"%%''
 +
 +''-DLLVM_PARALLEL_LINK_JOBS=2'' pour éviter que le link plante.
 +
 +''-DLLVM_INCLUDE_TESTS:BOOL=OFF -DCLANG_INCLUDE_TESTS:BOOL=OFF -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF -DLLVM_INCLUDE_UTILS:BOOL=OFF -DLLVM_INCLUDE_DOCS:BOOL=OFF -DLLVM_BUILD_UTILS:BOOL=OFF''
 ====Ubuntu==== ====Ubuntu====
  
Ligne 12: Ligne 29:
  
 <code bash> <code bash>
-cd /usr/share/keyrings +wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
-sudo wget https://apt.llvm.org/llvm-snapshot.gpg.key+
 </code> </code>
  
Ligne 21: Ligne 37:
  
 <code> <code>
-deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/unstable/ llvm-toolchain main +deb http://apt.llvm.org/mantic/ llvm-toolchain-mantic-17 main 
-deb-src [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/unstable/ llvm-toolchain main +deb-src http://apt.llvm.org/mantic/ llvm-toolchain-mantic-17 main
-# 15  +
-deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/unstable/ llvm-toolchain-15 main +
-deb-src [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/unstable/ llvm-toolchain-15 main+
 </code> </code>
  
Ligne 93: Ligne 106:
 [[https://linuxhint.com/update_alternatives_ubuntu|How to Use update-alternatives Command on Ubuntu]] {{ :prog:clang:how_to_use_update-alternatives_command_on_ubuntu_18_10_2022_14_54_18_.html |Archive du 01/05/2022 le 18/10/2022}} [[https://linuxhint.com/update_alternatives_ubuntu|How to Use update-alternatives Command on Ubuntu]] {{ :prog:clang:how_to_use_update-alternatives_command_on_ubuntu_18_10_2022_14_54_18_.html |Archive du 01/05/2022 le 18/10/2022}}
  
-=====Sanitizer===== +=====Options=====
-En plus de ceux commun avec [[prog:gcc|gcc]], il existe ''memory''.+
  
-====memory==== +  ''-ftime-trace'' 
-<code c main.c> +Affiche où clang passe du temps pour compilerLe fichier ''.json'' généré s'ouvre avec Chrome ''%%chrome://tracing%%''
-int main(int argc, char **argv) { +
-  int x[10]; +
-  x[0] = 1; +
-  return x[argc]; +
-+
-</code> +
-  clang -fsanitize=memory -g main.c -o main+
  
-  $ clang -fsanitize=memory -g main5.c -o main5 && ./main5==3981==WARNING: MemorySanitizer: use-of-uninitialized-value +[[https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/|time-tracetimeline flame chart profiler for Clang]] {{ :prog:clang:time-trace_timeline_flame_chart_profiler_for_clang_aras_website_2019-11-11_18_52_11_.html |Archive du 16/01/2019 le 11/11/2019}}
-      #0 0x492d5e in main /tmp/main5.c:4:+
-      #1 0x7f592c432461 in __libc_start_main .../sys-libs/glibc-2.25-r9/work/glibc-2.25/csu/../csu/libc-start.c:295 +
-      #2 0x41a129 in _start (/tmp/main5+0x41a129) +
-   +
-  SUMMARYMemorySanitizeruse-of-uninitialized-value /tmp/main5.c:4:3 in main+
  
-[[prog:valgrind|valgrind]] détecte l'erreur.+=====Erreurs=====
  
-  ==4011== Syscall param exit_group(status) contains uninitialised byte(s) +  * ''fatal error'iostream' file not found''
-  ==4011==    at 0x4F002B8_Exit (_exit.c:31) +
-  ==4011==    by 0x4E70423: __run_exit_handlers (exit.c:98) +
-  ==4011==    by 0x4E704DC: exit (exit.c:105) +
-  ==4011==    by 0x4E58468: (below main) (libc-start.c:329) +
-  ==4011==  Uninitialised value was created by a stack allocation +
-  ==4011==    at 0x400470: main (main5.c:1)+
  
-Instrumentation de la stdlib :+Les librairies standard ne sont pas trouvées. On peut commencer par vérifier si le paquet ''build-essential'' est installé.
  
-<WRAP center round important 60%> +Ensuite, les librairies standard ne sont pas forcément celles du gcc par défaut qui sont utilisées.
-L'utilisation de la libraire standard crée de nombreux faux positifs si la stdlib n'est pas instrumentée. +
-</WRAP>+
  
-Pour l'instrumenter, il faut suivre les instructions de [[https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo|MemorySanitizerLibcxxHowTo]] {{ :prog:clang:memorysanitizerlibcxxhowto_google_sanitizers_wiki_2020-02-13_22_56_51_.html |Archive du 29/01/2016 le 13/02/2020}}+Lancer ''clang -v'' pour trouver laquelle est en cours (''Selected GCC installation'').
  
-Ma tentative : 
-  * unwind de gcc sans sanitize : [[https://github.com/llvm-mirror/libunwind/blob/master/docs/BuildingLibunwind.rst|Building libunwind]] {{ :prog:clang:libunwind_buildinglibunwind.rst_at_master_llvm-mirror_libunwind_2020-02-13_22_58_36_.html |Archive du 29/01/2019 le 13/02/2020}} 
-  * libc++ and libc++abi avec -fsanitizer ([[https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo|MemorySanitizerLibcxxHowTo]]). Ajouter ''LDFLAGS=%%"%%-L .../llvm-project/build/lib/clang/8.0.0/x86_64-unknown-linux-gnu/lib -lunwind%%"%%'' si nécessaire. 
-  * compilation de poppler avec libc++ de clang [[https://github.com/google/oss-fuzz/blob/master/projects/poppler/build.sh]] 
 <code bash> <code bash>
-LDFLAGS="-L .../llvm-project/build/lib/clang/8.0.0/x86_64-unknown-linux-gnu/lib -lunwind -L.../llvm-project_libcxx_msan/build/lib -lc++abi" +clang -v
-CFLAGS="-fsanitize=memory -stdlib=libc++ -I.../llvm-project_libcxx_msan/build/include -I.../llvm-project_libcxx_msan/build/include/c++/v1" +
-CXXFLAGS="-fsanitize=memory -stdlib=libc++ -I.../llvm-project_libcxx_msan/build/include -I.../llvm-project_libcxx_msan/build/include/c++/v1" cmake .. +
--DCMAKE_BUILD_TYPE=debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang+++
 </code> </code>
-  * Compilation du programme de test sans succès : 
-<code> 
-clang++ 
--L .../llvm-project/build/lib/clang/8.0.0/x86_64-unknown-linux-gnu/lib -lunwind 
--L .../llvm-project_libcxx_msan/build/lib -lc++abi 
--fsanitize=memory,fuzzer -stdlib=libc++ 
--I.../llvm-project_libcxx_msan/build/include -I.../llvm-project_libcxx_msan/build/include/c++/v1 
--I ~/info/programmation/poppler/cpp/ 
-pdf_fuzzer.cc -o fuzz_target 
--L ~/info/programmation/poppler/build/ -lpoppler 
--L ~/info/programmation/poppler/build/cpp/ -lpoppler-cpp 
-</code> 
- 
-====Control Flow Integrity==== 
-[[https://www.usenix.org/sites/default/files/conference/protected-files/enigma_slides_serebryany.pdf|Sanitize, Fuzz, and Harden Your C++ Code]], {{ :prog:clang:enigma_slides_serebryany.pdf |Archive}} 
- 
-Nécessite l'option ''Gold'' de ''llvm''. 
- 
-Il est possible d'activer tous les cfi-* (''cfi-vcall'', ''cfi-ncall'', ''cfi-icall'', ''cfi-derived-cast'', ''cfi-unrelated-cast'') en une seule fois : ''-fsanitize=cfi''. 
- 
-<file c a.c> 
-#include <cstdio> 
-void Bad() { puts("BOOO"); } 
-struct Expr { 
-  long a[2]; 
-  long (*Op)(long *); 
-}; 
-int main(int argc, char **argv) { 
-  struct Expr e; 
-  // On écrit indirectement sur la variable Op. 
-  e.a[2 * argc] = (long)&Bad; 
-  e.Op(e.a); 
-} 
-</file> 
- 
-  * Sans le sanitizer 
- 
-  clang a.c && ./a.out 
- 
-  BOOO 
- 
-  * Avec le sanitizer 
- 
-  clang -flto -fsanitize=cfi -fvisibility=hidden -fno-sanitize-trap=cfi -g a.c && ./a.out 
  
 <code> <code>
-file.cpp:11:3runtime errorcontrol flow integrity check for type 'long (long *)' failed during indirect function call +Ubuntu clang version 14.0.6 
-file.cpp:2noteBad() defined here +Targetx86_64-pc-linux-gnu 
-SUMMARYUndefinedBehaviorSanitizer: undefined-behavior cfi_cast_strict.cpp:11:3 in+Thread modelposix 
 +InstalledDir/usr/lib/llvm-14/bin 
 +Found candidate GCC installation/usr/lib/gcc/x86_64-linux-gnu/10 
 +Found candidate GCC installation/usr/lib/gcc/x86_64-linux-gnu/11 
 +Found candidate GCC installation/usr/lib/gcc/x86_64-linux-gnu/12 
 +Found candidate GCC installation/usr/lib/gcc/x86_64-linux-gnu/9 
 +Selected GCC installation/usr/lib/gcc/x86_64-linux-gnu/12 
 +Candidate multilib: .;@m64 
 +Selected multilib.;@m64
 </code> </code>
-[[prog:valgrind|valgrind]] ne détecte pas l'erreur. 
  
-===Erreurs=== +<code bash
- +gcc -v
-  * ''runtime error: control flow integrity check for type '...' failed during cast to unrelated type (vtable address 0x000000000000)'' +
- +
-Le fait que l'adresse de la ''vtable'' soit nulle indique que la classe n'en a pas. Si une ou plusieurs méthodes sont déclarés virtuelles, elles ont été optimisées par le compilateur. +
- +
-La solution est donc de supprimer (après vérification) la déclaration ''virtual''+
- +
-[[https://bugs.chromium.org/p/chromium/issues/detail?id=515973|Issue 515973: Invalid cast in SkTArray.h]] {{ :prog:clang:515973_-_invalid_cast_in_sktarray.h_-_chromium_2021-06-20_12_00_33_.html |Archive du 31/07/2015 le 20/06/2021}} +
- +
-[[https://codereview.chromium.org/1259143006/patch/1/10001|Unified Diff: include/core/SkTArray.h]] {{ :prog:clang:include_core_sktarray.h_-_issue_1259143006_remove_unnecessary_virtual_destructor_on_sktarray_-_code_review_2021-06-20_12_02_40_.html |Archive du 31/07/2015 le 20/06/2021}} +
- +
-  * ''cast to unrelated type'' ''aligned_buffer.h'' +
- +
-<code> +
-/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/g++-v11/ext/aligned_buffer.h:115:16: runtime error: control flow integrity check for type '...' failed during cast to unrelated type (vtable address 0x747365742f617461) +
-0x747365742f617461: note: invalid vtable +
-<memory cannot be printed> +
-/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/g++-v11/ext/aligned_buffer.h:115:16: note: check failed in ..., vtable located in (unknown) +
-SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/g++-v11/ext/aligned_buffer.h:115:16 in+
 </code> </code>
- 
-L'utilisation de ''std::make_shared'' couplé avec le ''-fsanitize=cfi'' peu poser problème. Le constructeur de ''shared_ptr'' va vouloir caster la zone mémoire avant d'appeler le constructeur. La zone mémoire étant non initialisée, le sanitizer ne va pas reconnaitre le pointeur ''vtable''. 
- 
-Ce problème existe dans l'implémentation sous clang et gcc. 
- 
-''clang'' a résolu le problème en ajoutant '' _LIBCPP_NO_CFI'' à la fonction ''%%_Storage::__get_elem%%'' dans le fichier ''memory''. 
- 
-Pour ''gcc'', il faut faire la même chose avec ''%%__attribute__((__no_sanitize__("cfi")))%%'' pour les fonctions ''%%__aligned_buffer::%%_M_ptr'' dans le fichier ''aligned_buffer.h''. 
- 
-[[https://www.mail-archive.com/llvm-bugs@lists.llvm.org/msg48282.html|New: Recent shared_ptr storage change causes CFI cast failures during make_shared]] {{ :prog:clang:llvm-bugs_bug_48993_new_recent_shared_ptr_storage_change_https_reviews.llvm.org_d91201_causes_cfi_cast_failures_during_make_shared_2021-06-23_21_13_22_.html |Archive du 01/02/2021 le 23/06/2021}} 
- 
-[[https://reviews.llvm.org/D95827|Avoid cast<T*> before T is constructed to pacify CFI checks]] {{ :prog:clang:⚙_d95827_avoid_cast_t_before_t_is_constructed_to_pacify_cfi_checks_2021-06-23_21_13_34_.html |Archive du 01/02/2021 le 23/06/2021}} 
- 
-[[https://reviews.llvm.org/D96063|Disable CFI in __get_elem to allow casting a pointer to uninitialized memory]] {{ :prog:clang:⚙_d96063_🍒_disable_cfi_in_get_elem_to_allow_casting_a_pointer_to_uninitialized_memory_2021-06-23_21_14_00_.html |Archive du 04/02/2021 le 23/06/2021}} 
- 
-  * RTTI symbol not found for class 
- 
-Pour diagnostiquer une erreur de sanitizer, il est possible de mettre un point d'arrêt avec [[prog:clang#gdb|gdb]]. 
- 
-Il est possible d'avoir des warnings de la part de gdb à propos de RTTI (''warning: RTTI symbol not found for class''). Dans ce cas, le plantage du sanitizer cfi est probablement un faux positif car il travaille sur les informations RTTI. 
- 
-Exemple de message d'erreur généré par le sanitizer à l'exécution. 
- 
-  /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/bits/std_function.h:590:9: runtime error: control flow integrity check for type 'std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (const std::_Any_data &)' failed during indirect function call 
-  /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/bits/std_function.h:289: note: std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_State_baseV2::_Setter<std::shared_ptr<restbed::Response>, std::shared_ptr<restbed::Response> const&> >::_M_invoke(std::_Any_data const&) defined here 
-  /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/bits/std_function.h:590:9: note: check failed in /mnt/c/j/build/clang_cfi/test/backend/data/test_load_vertical_eccentric, destination function located in /mnt/c/j/build/clang_cfi/_deps/restbed-build/librestbed.so.4 
-  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/bits/std_function.h:590:9 in 
- 
-Dans cet exemple, la classe ''restbed::Response'' a bien été compilée avec l'option ''%%__attribute__((visibility ("default")))%%''. 
- 
-Ces erreurs peuvent apparaître quand le sanitizer travaille avec une librairie dynamique. Pour que le sanitizer cfi réussisse son travail, il faut que les librairies compilées avec le sanitizer cfi soient liées statiquement. 
- 
-====Pile==== 
-<file c a.c> 
-void Bad() { puts("BOOO"); exit(0); } 
-int main(int argc, char **argv) { 
-  long array[10]; 
-  array[argc * 13] = (long)&Bad; 
-} 
-</file> 
- 
-Nécessite l'option ''Gold'' de ''llvm''. L'exemple ne marche que pour du 64 bits. 
- 
-  * Sans protection 
- 
-  clang a.c && ./a.out 
- 
-  BOOO 
-  Segmentation fault 
- 
-  * Avec protection ''safe-stack'' 
- 
-  clang -fsanitize=safe-stack a.c && ./a.out 
- 
-  Pas de message d'erreur... 
- 
-  * Avec protection ''cfi'' 
- 
-  clang++ cfi_cast_strict.cpp -O0 -fsanitize=cfi -flto=thin -fvisibility=hidden -fno-sanitize-trap=cfi 
  
 <code> <code>
-BOOO +gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)
-UndefinedBehaviorSanitizer:DEADLYSIGNAL +
-==12856==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7f6e125389a0 (pc 0x7f6e125389a0 bp 0x7ffcbb5f9370 sp 0x7ffcbb5f92a8 T12856) +
-==12856==The signal is caused by a READ memory access. +
-==12856==Hint: PC is at a non-executable region. Maybe a wild jump? +
-    #0 0x7f6e125389a0  (/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libstdc++.so.6+0x2209a0) +
- +
-UndefinedBehaviorSanitizer can not provide additional info. +
-SUMMARY: UndefinedBehaviorSanitizer: SEGV (/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libstdc++.so.6+0x2209a0) +
-==12856==ABORTING+
 </code> </code>
  
-[[prog:valgrind|valgrind]] détecte l'erreur. +Il faut donc installer les entêtes de gcc-12.
- +
-====gdb==== +
- +
-Pour arrêter le debug lors d'une erreur, on peut utiliser les symboles : +
- +
-  __ubsan::ScopedReport::~ScopedReport +
-  __tsan::ReportRace +
- +
-[[https://stackoverflow.com/questions/30809022/how-can-i-break-on-ubsan-reports-in-gdb-and-continue|How can I break on UBSan reports in gdb and continue?]] {{ :prog:gcc:c_-_how_can_i_break_on_ubsan_reports_in_gdb_and_continue_-_stack_overflow_2021-04-18_19_24_58_.html |Archive du 12/06/2015 le 18/04/2021}} +
- +
-=====Fuzzer===== +
- +
-[[https://labsblog.f-secure.com/2017/06/22/super-awesome-fuzzing-part-one/|Super Awesome Fuzzing, Part One]] {{ :prog:clang:super_awesome_fuzzing_part_one_-_f-secure_blog_2020-02-13_22_52_43_.html |Archive du 22/06/2017 le 13/02/2020}} +
- +
-[[https://raw.githubusercontent.com/google/fuzzer-test-suite/master/tutorial/fuzz_me.cc|fuzz_me.c]] {{ :prog:clang:fuzz_me.cc |Archive}} +
- +
-Il faut créer un fichier source qui ne contient qu'une seule fonction. La fonction ''main'' est dans l'archive statique ''libFuzzer.a''+
-<code c> +
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +
-</code> +
- +
-L'option de compilation ''-fsanitize=fuzzer'' est obligatoire mais il peut être utile de rajouter ''-fno-omit-frame-pointer -g -fsanitize=address,undefined''+
- +
-  clang++ -fno-omit-frame-pointer -g -fsanitize=address,undefined,fuzzer fuzz_me.cc +
- +
-<WRAP center round tip 60%> +
-Si vous avez le message : ''error adding symbols: DSO missing from command line'', il faut rajouter ''-lgcc_s''+
-</WRAP> +
- +
-[[https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md|Pour aller plus loin]], même si ça possède de nombreuses fonctionnalités, je préfère [[prog:fuzzer:afl|afl]] mais une étude comparative va finir par s'imposer. {{ :prog:clang:fuzzing_libfuzzertutorial.md_at_master_google_fuzzing_2020-02-13_22_51_09_.html |Archive du 27/09/2020 le 13/02/2020}} +
- +
-=====Couverture de code===== +
- +
-Options à ajouter à la compilation : ''-O0 -fprofile-instr-generate -fcoverage-mapping -mllvm -runtime-counter-relocation'' +
- +
-Options à ajouter au lieur : ''-fprofile-instr-generate -fcoverage-mapping'' +
- +
-Puis exécuter le ou les programmes. Attention, pas d'exécution en parallèle. +
- +
-<code bash> +
-shopt -s globstar dotglob +
-llvm-profdata-11 merge -output=code.profdata **/*.profraw +
-mkdir build/coverage +
-llvm-cov-11 show -use-color --format html -instr-profile=code.profdata ./build/test/calc/geotechnical/test_calc_meyerhof -output-dir=build/coverage +
-find build/coverage -name "*.html" -exec tidy -i -m --doctype html5 --drop-empty-elements no {} \; +
-find build/coverage -name "*.html" -exec sed -i -r "s#Created: .*-.*-.* .*:.*h4#</h4#g" {} \; +
-</code> +
- +
-On commence par fusionner toutes les traces avec ''llvm-profdata'' puis on génère le rapport au format HTML. +
- +
-En option, on indente et on supprime la date pour qu'un diff simple puisse se faire. +
- +
-=====Options===== +
- +
-  * ''-ftime-trace'' +
-Affiche où clang passe du temps pour compiler. Le fichier ''.json'' généré s'ouvre avec Chrome ''%%chrome://tracing%%'' +
- +
-[[https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/|time-trace: timeline / flame chart profiler for Clang]] {{ :prog:clang:time-trace_timeline_flame_chart_profiler_for_clang_aras_website_2019-11-11_18_52_11_.html |Archive du 16/01/2019 le 11/11/2019}} +
- +
-=====Utilitaires===== +
-====clang-include-fixer==== +
-Détecte les ''#include'' manquants.+
  
 <code bash> <code bash>
-# Compilation du code source +sudo apt install libstdc++-12-dev
-mkdir build +
-cd build +
-# On doit activer set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +
-cmake ..  +
-# Si nécessaire +
-make -j9 check +
-python2 /usr/lib/llvm/9/share/clang/run-find-all-symbols.py -binary=/usr/lib/llvm/9/bin/find-all-symbols +
-clang-include-fixer -db=yaml ../src/2lgc/pattern/publisher/publisher_grpc.h+
 </code> </code>
  
-Attention, contrairement à IWYU, il y a des limitations : +[[https://stackoverflow.com/questions/26333823/clang-doesnt-see-basic-headers|Clang doesn't see basic headers]] {{ :prog:clang:c_-_clang_doesn_t_see_basic_headers_-_stack_overflow_11_05_2023_11_53_28_.html |Archive du 13/10/2014 le 11/05/2023}}
-  * Ne détecte pas les ''#include'' en trop, +
-  * Ne détecte pas les ''#include'' qui pourrait être optimisés (''meta.h'' à la place de ''small.h''), +
-  * Ne propose qu'un seul ''#include'' à ajouter à la fois,+
prog/clang.1683705517.txt.gz · Dernière modification : 2023/05/10 09:58 de root