@@ -78,6 +78,9 @@ static inline char* GetEnv(const char* Var_Name) {
7878#include " llvm/Support/Casting.h"
7979#include " llvm/Support/Path.h"
8080
81+ // std::regex breaks pytorch's jit: pytorch/pytorch#49460
82+ #include " llvm/Support/Regex.h"
83+
8184#ifdef USE_CLING
8285
8386#include " cling/Interpreter/DynamicLibraryManager.h"
@@ -163,20 +166,57 @@ inline void codeComplete(std::vector<std::string>& Results,
163166 std::vector<std::string> results;
164167 size_t column = complete_column;
165168 I.codeComplete (code, column, results);
169+ std::string error;
170+ llvm::Error Err = llvm::Error::success ();
171+ // Regex patterns
172+ llvm::Regex removeDefinition (" \\ [\\ #.*\\ #\\ ]" );
173+ llvm::Regex removeVariableName (" (\\ |\\ *)+(\\ w+)(\\ #\\ >)" );
174+ llvm::Regex removeTrailingSpace (" \\ *(\\ #\\ >)" );
175+ llvm::Regex removeTags (" \\ <\\ #([^#>]*)\\ #\\ >" );
166176
167177 // append cleaned results
168178 for (auto & r : results) {
169- // remove the definition at the beginning (for example [#int#])
170- r = std::regex_replace (r, std::regex (" \\ [\\ #.*\\ #\\ ]" ), " " );
179+ // remove the definition at the beginning (e.g., [#int#])
180+ r = removeDefinition.sub (" " , r, &error);
181+ if (!error.empty ()) {
182+ Err = llvm::make_error<llvm::StringError>(error,
183+ llvm::inconvertibleErrorCode ());
184+ llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (),
185+ " Invalid substitution in CodeComplete" );
186+ return ;
187+ }
171188 // remove the variable name in <#type name#>
172- r = std::regex_replace (r, std::regex (" (\\ |\\ *)+(\\ w+)(\\ #\\ >)" ), " $1$3" );
189+ r = removeVariableName.sub (" $1$3" , r, &error);
190+ if (!error.empty ()) {
191+ Err = llvm::make_error<llvm::StringError>(error,
192+ llvm::inconvertibleErrorCode ());
193+ llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (),
194+ " Invalid substitution in CodeComplete" );
195+ return ;
196+ }
173197 // remove unnecessary space at the end of <#type #>
174- r = std::regex_replace (r, std::regex (" \\ *(\\ #\\ >)" ), " $1" );
198+ r = removeTrailingSpace.sub (" $1" , r, &error);
199+ if (!error.empty ()) {
200+ Err = llvm::make_error<llvm::StringError>(error,
201+ llvm::inconvertibleErrorCode ());
202+ llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (),
203+ " Invalid substitution in CodeComplete" );
204+ return ;
205+ }
175206 // remove <# #> to keep only the type
176- r = std::regex_replace (r, std::regex (" \\ <\\ #([^#>]*)\\ #\\ >" ), " $1" );
207+ r = removeTags.sub (" $1" , r, &error);
208+ if (!error.empty ()) {
209+ Err = llvm::make_error<llvm::StringError>(error,
210+ llvm::inconvertibleErrorCode ());
211+ llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (),
212+ " Invalid substitution in CodeComplete" );
213+ return ;
214+ }
215+
177216 if (r.find (code) == 0 )
178217 Results.push_back (r);
179218 }
219+ llvm::consumeError (std::move (Err));
180220}
181221
182222} // namespace compat
0 commit comments